diff options
author | Ali Saidi <Ali.Saidi@ARM.com> | 2012-06-05 01:23:09 -0400 |
---|---|---|
committer | Ali Saidi <Ali.Saidi@ARM.com> | 2012-06-05 01:23:09 -0400 |
commit | 6df196b71e058b2c827e1027416155ac8ec8cf9f (patch) | |
tree | e2adf25e5628078f8e7c7d89c97130c8962e0ab0 /src/cpu/o3 | |
parent | aec7a4411683d8b10684f8f70093bcbbc2de8b55 (diff) | |
download | gem5-6df196b71e058b2c827e1027416155ac8ec8cf9f.tar.xz |
O3: Clean up the O3 structures and try to pack them a bit better.
DynInst is extremely large the hope is that this re-organization will put the
most used members close to each other.
Diffstat (limited to 'src/cpu/o3')
-rw-r--r-- | src/cpu/o3/bpred_unit.hh | 17 | ||||
-rw-r--r-- | src/cpu/o3/comm.hh | 23 | ||||
-rw-r--r-- | src/cpu/o3/commit_impl.hh | 10 | ||||
-rw-r--r-- | src/cpu/o3/decode_impl.hh | 2 | ||||
-rw-r--r-- | src/cpu/o3/dyn_inst.hh | 23 | ||||
-rw-r--r-- | src/cpu/o3/dyn_inst_impl.hh | 3 | ||||
-rw-r--r-- | src/cpu/o3/iew_impl.hh | 4 | ||||
-rw-r--r-- | src/cpu/o3/inst_queue_impl.hh | 20 | ||||
-rw-r--r-- | src/cpu/o3/lsq_unit.hh | 35 | ||||
-rw-r--r-- | src/cpu/o3/lsq_unit_impl.hh | 18 | ||||
-rw-r--r-- | src/cpu/o3/rename_impl.hh | 4 |
11 files changed, 78 insertions, 81 deletions
diff --git a/src/cpu/o3/bpred_unit.hh b/src/cpu/o3/bpred_unit.hh index 673472b69..8bfab11a9 100644 --- a/src/cpu/o3/bpred_unit.hh +++ b/src/cpu/o3/bpred_unit.hh @@ -206,9 +206,9 @@ class BPredUnit PredictorHistory(const InstSeqNum &seq_num, Addr instPC, bool pred_taken, void *bp_history, ThreadID _tid) - : seqNum(seq_num), pc(instPC), RASTarget(0), RASIndex(0), - tid(_tid), predTaken(pred_taken), usedRAS(0), - wasCall(0), wasReturn(0), validBTB(0), bpHistory(bp_history) + : seqNum(seq_num), pc(instPC), bpHistory(bp_history), RASTarget(0), + RASIndex(0), tid(_tid), predTaken(pred_taken), usedRAS(0), + wasCall(0), wasReturn(0), validBTB(0) {} bool operator==(const PredictorHistory &entry) const { @@ -221,6 +221,12 @@ class BPredUnit /** The PC associated with the sequence number. */ Addr pc; + /** Pointer to the history object passed back from the branch + * predictor. It is used to update or restore state of the + * branch predictor. + */ + void *bpHistory; + /** The RAS target (only valid if a return). */ TheISA::PCState RASTarget; @@ -243,11 +249,6 @@ class BPredUnit bool wasReturn; /** Whether or not the instruction had a valid BTB entry. */ bool validBTB; - /** Pointer to the history object passed back from the branch - * predictor. It is used to update or restore state of the - * branch predictor. - */ - void *bpHistory; }; typedef std::list<PredictorHistory> History; diff --git a/src/cpu/o3/comm.hh b/src/cpu/o3/comm.hh index 053d4f6be..31d252c73 100644 --- a/src/cpu/o3/comm.hh +++ b/src/cpu/o3/comm.hh @@ -96,15 +96,14 @@ struct DefaultIEWDefaultCommit { int size; DynInstPtr insts[Impl::MaxWidth]; - - bool squash[Impl::MaxThreads]; - bool branchMispredict[Impl::MaxThreads]; DynInstPtr mispredictInst[Impl::MaxThreads]; - bool branchTaken[Impl::MaxThreads]; Addr mispredPC[Impl::MaxThreads]; - TheISA::PCState pc[Impl::MaxThreads]; InstSeqNum squashedSeqNum[Impl::MaxThreads]; + TheISA::PCState pc[Impl::MaxThreads]; + bool squash[Impl::MaxThreads]; + bool branchMispredict[Impl::MaxThreads]; + bool branchTaken[Impl::MaxThreads]; bool includeSquashInst[Impl::MaxThreads]; }; @@ -122,21 +121,17 @@ template<class Impl> struct TimeBufStruct { typedef typename Impl::DynInstPtr DynInstPtr; struct decodeComm { - bool squash; - bool predIncorrect; uint64_t branchAddr; - InstSeqNum doneSeqNum; - - // @todo: Might want to package this kind of branch stuff into a single - // struct as it is used pretty frequently. - bool branchMispredict; DynInstPtr mispredictInst; - bool branchTaken; + DynInstPtr squashInst; Addr mispredPC; TheISA::PCState nextPC; - DynInstPtr squashInst; unsigned branchCount; + bool squash; + bool predIncorrect; + bool branchMispredict; + bool branchTaken; }; decodeComm decodeInfo[Impl::MaxThreads]; diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index 1bf493871..45f5bc02b 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -1244,11 +1244,11 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num) head_inst->microPC(), head_inst->seqNum, head_inst->staticInst->disassemble(head_inst->instAddr())); - DPRINTFR(O3PipeView, "O3PipeView:decode:%llu\n", head_inst->decodeTick); - DPRINTFR(O3PipeView, "O3PipeView:rename:%llu\n", head_inst->renameTick); - DPRINTFR(O3PipeView, "O3PipeView:dispatch:%llu\n", head_inst->dispatchTick); - DPRINTFR(O3PipeView, "O3PipeView:issue:%llu\n", head_inst->issueTick); - DPRINTFR(O3PipeView, "O3PipeView:complete:%llu\n", head_inst->completeTick); + DPRINTFR(O3PipeView, "O3PipeView:decode:%llu\n", head_inst->fetchTick + head_inst->decodeTick); + DPRINTFR(O3PipeView, "O3PipeView:rename:%llu\n", head_inst->fetchTick + head_inst->renameTick); + DPRINTFR(O3PipeView, "O3PipeView:dispatch:%llu\n", head_inst->fetchTick + head_inst->dispatchTick); + DPRINTFR(O3PipeView, "O3PipeView:issue:%llu\n", head_inst->fetchTick + head_inst->issueTick); + DPRINTFR(O3PipeView, "O3PipeView:complete:%llu\n", head_inst->fetchTick + head_inst->completeTick); DPRINTFR(O3PipeView, "O3PipeView:retire:%llu\n", curTick()); #endif diff --git a/src/cpu/o3/decode_impl.hh b/src/cpu/o3/decode_impl.hh index fd8dc834b..315d53155 100644 --- a/src/cpu/o3/decode_impl.hh +++ b/src/cpu/o3/decode_impl.hh @@ -709,7 +709,7 @@ DefaultDecode<Impl>::decodeInsts(ThreadID tid) --insts_available; #if TRACING_ON - inst->decodeTick = curTick(); + inst->decodeTick = curTick() - inst->fetchTick; #endif // Ensure that if it was predicted as a branch, it really is a diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh index ed947d92f..8acbf3443 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -107,26 +107,28 @@ class BaseO3DynInst : public BaseDynInst<Impl> void initVars(); protected: + /** Values to be written to the destination misc. registers. */ + MiscReg _destMiscRegVal[TheISA::MaxMiscDestRegs]; + /** Indexes of the destination misc. registers. They are needed to defer * the write accesses to the misc. registers until the commit stage, when * the instruction is out of its speculative state. */ - int _destMiscRegIdx[MaxInstDestRegs]; - /** Values to be written to the destination misc. registers. */ - MiscReg _destMiscRegVal[MaxInstDestRegs]; + short _destMiscRegIdx[TheISA::MaxMiscDestRegs]; + /** Number of destination misc. registers. */ - int _numDestMiscRegs; + uint8_t _numDestMiscRegs; - public: + public: #if TRACING_ON /** Tick records used for the pipeline activity viewer. */ Tick fetchTick; - Tick decodeTick; - Tick renameTick; - Tick dispatchTick; - Tick issueTick; - Tick completeTick; + uint32_t decodeTick; + uint32_t renameTick; + uint32_t dispatchTick; + uint32_t issueTick; + uint32_t completeTick; #endif /** Reads a misc. register, including any side-effects the read @@ -145,6 +147,7 @@ class BaseO3DynInst : public BaseDynInst<Impl> /** Writes to misc. registers are recorded and deferred until the * commit stage, when updateMiscRegs() is called. */ + assert(_numDestMiscRegs < TheISA::MaxMiscDestRegs); _destMiscRegIdx[_numDestMiscRegs] = misc_reg; _destMiscRegVal[_numDestMiscRegs] = val; _numDestMiscRegs++; diff --git a/src/cpu/o3/dyn_inst_impl.hh b/src/cpu/o3/dyn_inst_impl.hh index 2870d40fe..85778aadc 100644 --- a/src/cpu/o3/dyn_inst_impl.hh +++ b/src/cpu/o3/dyn_inst_impl.hh @@ -75,9 +75,10 @@ BaseO3DynInst<Impl>::initVars() for (int i = 0; i < this->staticInst->numSrcRegs(); i++) { this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i); - this->_readySrcRegIdx[i] = 0; } + this->_readySrcRegIdx.reset(); + _numDestMiscRegs = 0; #if TRACING_ON diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index b306e6e58..60f4604a2 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -1152,7 +1152,7 @@ DefaultIEW<Impl>::dispatchInsts(ThreadID tid) ++iewDispatchedInsts; #if TRACING_ON - inst->dispatchTick = curTick(); + inst->dispatchTick = curTick() - inst->fetchTick; #endif } @@ -1617,7 +1617,7 @@ DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst) iewExecutedInsts++; #if TRACING_ON - inst->completeTick = curTick(); + inst->completeTick = curTick() - inst->fetchTick; #endif // diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh index 2c0779a03..ae5f93c38 100644 --- a/src/cpu/o3/inst_queue_impl.hh +++ b/src/cpu/o3/inst_queue_impl.hh @@ -859,7 +859,7 @@ InstructionQueue<Impl>::scheduleReadyInsts() ++total_issued; #if TRACING_ON - issuing_inst->issueTick = curTick(); + issuing_inst->issueTick = curTick() - issuing_inst->fetchTick; #endif if (!issuing_inst->isMemRef()) { @@ -1054,8 +1054,8 @@ InstructionQueue<Impl>::rescheduleMemInst(DynInstPtr &resched_inst) DPRINTF(IQ, "Rescheduling mem inst [sn:%lli]\n", resched_inst->seqNum); // Reset DTB translation state - resched_inst->translationStarted = false; - resched_inst->translationCompleted = false; + resched_inst->translationStarted(false); + resched_inst->translationCompleted(false); resched_inst->clearCanIssue(); memDepUnit[resched_inst->threadNumber].reschedule(resched_inst); @@ -1079,7 +1079,7 @@ InstructionQueue<Impl>::completeMemInst(DynInstPtr &completed_inst) ++freeEntries; - completed_inst->memOpDone = true; + completed_inst->memOpDone(true); memDepUnit[tid].completed(completed_inst); count[tid]--; @@ -1098,7 +1098,7 @@ InstructionQueue<Impl>::getDeferredMemInstToExecute() { for (ListIt it = deferredMemInsts.begin(); it != deferredMemInsts.end(); ++it) { - if ((*it)->translationCompleted || (*it)->isSquashed()) { + if ((*it)->translationCompleted() || (*it)->isSquashed()) { DynInstPtr ret = *it; deferredMemInsts.erase(it); return ret; @@ -1165,7 +1165,7 @@ InstructionQueue<Impl>::doSquash(ThreadID tid) if (!squashed_inst->isIssued() || (squashed_inst->isMemRef() && - !squashed_inst->memOpDone)) { + !squashed_inst->memOpDone())) { DPRINTF(IQ, "[tid:%i]: Instruction [sn:%lli] PC %s squashed.\n", tid, squashed_inst->seqNum, squashed_inst->pcState()); @@ -1456,7 +1456,7 @@ InstructionQueue<Impl>::dumpInsts() ++valid_num; cprintf("Count:%i\n", valid_num); } else if ((*inst_list_it)->isMemRef() && - !(*inst_list_it)->memOpDone) { + !(*inst_list_it)->memOpDone()) { // Loads that have not been marked as executed // still count towards the total instructions. ++valid_num; @@ -1473,7 +1473,7 @@ InstructionQueue<Impl>::dumpInsts() (*inst_list_it)->isSquashed()); if ((*inst_list_it)->isMemRef()) { - cprintf("MemOpDone:%i\n", (*inst_list_it)->memOpDone); + cprintf("MemOpDone:%i\n", (*inst_list_it)->memOpDone()); } cprintf("\n"); @@ -1498,7 +1498,7 @@ InstructionQueue<Impl>::dumpInsts() ++valid_num; cprintf("Count:%i\n", valid_num); } else if ((*inst_list_it)->isMemRef() && - !(*inst_list_it)->memOpDone) { + !(*inst_list_it)->memOpDone()) { // Loads that have not been marked as executed // still count towards the total instructions. ++valid_num; @@ -1515,7 +1515,7 @@ InstructionQueue<Impl>::dumpInsts() (*inst_list_it)->isSquashed()); if ((*inst_list_it)->isMemRef()) { - cprintf("MemOpDone:%i\n", (*inst_list_it)->memOpDone); + cprintf("MemOpDone:%i\n", (*inst_list_it)->memOpDone()); } cprintf("\n"); diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh index c3bb8f7cd..7093b5fee 100644 --- a/src/cpu/o3/lsq_unit.hh +++ b/src/cpu/o3/lsq_unit.hh @@ -275,28 +275,28 @@ class LSQUnit { public: /** Default constructor. */ LSQSenderState() - : noWB(false), isSplit(false), pktToSend(false), outstanding(1), - mainPkt(NULL), pendingPacket(NULL) - { } + : mainPkt(NULL), pendingPacket(NULL), outstanding(1), + noWB(false), isSplit(false), pktToSend(false) + { } /** Instruction who initiated the access to memory. */ DynInstPtr inst; + /** The main packet from a split load, used during writeback. */ + PacketPtr mainPkt; + /** A second packet from a split store that needs sending. */ + PacketPtr pendingPacket; + /** The LQ/SQ index of the instruction. */ + uint8_t idx; + /** Number of outstanding packets to complete. */ + uint8_t outstanding; /** Whether or not it is a load. */ bool isLoad; - /** The LQ/SQ index of the instruction. */ - int idx; /** Whether or not the instruction will need to writeback. */ bool noWB; /** Whether or not this access is split in two. */ bool isSplit; /** Whether or not there is a packet that needs sending. */ bool pktToSend; - /** Number of outstanding packets to complete. */ - int outstanding; - /** The main packet from a split load, used during writeback. */ - PacketPtr mainPkt; - /** A second packet from a split store that needs sending. */ - PacketPtr pendingPacket; /** Completes a packet and returns whether the access is finished. */ inline bool complete() { return --outstanding == 0; } @@ -342,7 +342,8 @@ class LSQUnit { { std::memset(data, 0, sizeof(data)); } - + /** The store data. */ + char data[16]; /** The store instruction. */ DynInstPtr inst; /** The request for the store. */ @@ -351,9 +352,7 @@ class LSQUnit { RequestPtr sreqLow; RequestPtr sreqHigh; /** The size of the store. */ - int size; - /** The store data. */ - char data[16]; + uint8_t size; /** Whether or not the store is split into two requests. */ bool isSplit; /** Whether or not the store can writeback. */ @@ -593,9 +592,9 @@ LSQUnit<Impl>::read(Request *req, Request *sreqLow, Request *sreqHigh, // Disable recording the result temporarily. Writing to misc // regs normally updates the result, but this is not the // desired behavior when handling store conditionals. - load_inst->recordResult = false; + load_inst->recordResult(false); TheISA::handleLockedRead(load_inst.get(), req); - load_inst->recordResult = true; + load_inst->recordResult(true); } if (req->isMmappedIpr()) { @@ -651,7 +650,7 @@ LSQUnit<Impl>::read(Request *req, Request *sreqLow, Request *sreqHigh, else if (storeQueue[store_idx].inst->uncacheable()) continue; - assert(storeQueue[store_idx].inst->effAddrValid); + assert(storeQueue[store_idx].inst->effAddrValid()); // Check if the store data is within the lower and upper bounds of // addresses that the request needs. diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index 4f82ad9e3..a878b1540 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -465,7 +465,7 @@ LSQUnit<Impl>::checkSnoop(PacketPtr pkt) while (load_idx != loadTail) { DynInstPtr ld_inst = loadQueue[load_idx]; - if (!ld_inst->effAddrValid || ld_inst->uncacheable()) { + if (!ld_inst->effAddrValid() || ld_inst->uncacheable()) { incrLdIdx(load_idx); continue; } @@ -475,7 +475,7 @@ LSQUnit<Impl>::checkSnoop(PacketPtr pkt) ld_inst->seqNum, load_addr, invalidate_addr); if (load_addr == invalidate_addr) { - if (ld_inst->possibleLoadViolation) { + if (ld_inst->possibleLoadViolation()) { DPRINTF(LSQUnit, "Conflicting load at addr %#x [sn:%lli]\n", ld_inst->physEffAddr, pkt->getAddr(), ld_inst->seqNum); @@ -485,7 +485,7 @@ LSQUnit<Impl>::checkSnoop(PacketPtr pkt) // If a older load checks this and it's true // then we might have missed the snoop // in which case we need to invalidate to be sure - ld_inst->hitExternalSnoop = true; + ld_inst->hitExternalSnoop(true); } } incrLdIdx(load_idx); @@ -507,7 +507,7 @@ LSQUnit<Impl>::checkViolations(int load_idx, DynInstPtr &inst) */ while (load_idx != loadTail) { DynInstPtr ld_inst = loadQueue[load_idx]; - if (!ld_inst->effAddrValid || ld_inst->uncacheable()) { + if (!ld_inst->effAddrValid() || ld_inst->uncacheable()) { incrLdIdx(load_idx); continue; } @@ -521,7 +521,7 @@ LSQUnit<Impl>::checkViolations(int load_idx, DynInstPtr &inst) // If this load is to the same block as an external snoop // invalidate that we've observed then the load needs to be // squashed as it could have newer data - if (ld_inst->hitExternalSnoop) { + if (ld_inst->hitExternalSnoop()) { if (!memDepViolator || ld_inst->seqNum < memDepViolator->seqNum) { DPRINTF(LSQUnit, "Detected fault with inst [sn:%lli] " @@ -540,7 +540,7 @@ LSQUnit<Impl>::checkViolations(int load_idx, DynInstPtr &inst) // Otherwise, mark the load has a possible load violation // and if we see a snoop before it's commited, we need to squash - ld_inst->possibleLoadViolation = true; + ld_inst->possibleLoadViolation(true); DPRINTF(LSQUnit, "Found possible load violaiton at addr: %#x" " between instructions [sn:%lli] and [sn:%lli]\n", inst_eff_addr1, inst->seqNum, ld_inst->seqNum); @@ -610,7 +610,7 @@ LSQUnit<Impl>::executeLoad(DynInstPtr &inst) iewStage->instToCommit(inst); iewStage->activityThisCycle(); } else if (!loadBlocked()) { - assert(inst->effAddrValid); + assert(inst->effAddrValid()); int load_idx = inst->lqIdx; incrLdIdx(load_idx); @@ -857,9 +857,9 @@ LSQUnit<Impl>::writebackStores() // Disable recording the result temporarily. Writing to // misc regs normally updates the result, but this is not // the desired behavior when handling store conditionals. - inst->recordResult = false; + inst->recordResult(false); bool success = TheISA::handleLockedWrite(inst.get(), req); - inst->recordResult = true; + inst->recordResult(true); if (!success) { // Instantly complete this store. diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index 678927813..592bc059f 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -692,7 +692,7 @@ DefaultRename<Impl>::renameInsts(ThreadID tid) ++renamed_insts; #if TRACING_ON - inst->renameTick = curTick(); + inst->renameTick = curTick() - inst->fetchTick; #endif // Put instruction in rename queue. @@ -997,8 +997,6 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid) panic("Reg index is out of bound: %d.", src_reg); } - inst->flattenSrcReg(src_idx, flat_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); |