summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2011-02-12 10:14:36 -0500
committerKorey Sewell <ksewell@umich.edu>2011-02-12 10:14:36 -0500
commit6713dbfe080df4dd04b0f29b5f2fbd6e221ffebf (patch)
tree9bc390854c24cf308f93fe7ab44928a8facaff59 /src
parentaf67631790afbfeba01b05f7ae2ca54ae27428f1 (diff)
downloadgem5-6713dbfe080df4dd04b0f29b5f2fbd6e221ffebf.tar.xz
inorder: cache instruction schedules
first step in a optimization to not dynamically allocate an instruction schedule for every instruction but rather used cached schedules
Diffstat (limited to 'src')
-rw-r--r--src/cpu/inorder/cpu.cc6
-rw-r--r--src/cpu/inorder/cpu.hh56
-rw-r--r--src/cpu/inorder/pipeline_traits.hh1
3 files changed, 62 insertions, 1 deletions
diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc
index ffdcae7df..39357cd30 100644
--- a/src/cpu/inorder/cpu.cc
+++ b/src/cpu/inorder/cpu.cc
@@ -334,9 +334,13 @@ InOrderCPU::InOrderCPU(Params *params)
dummyReqInst = new InOrderDynInst(this, NULL, 0, 0, 0);
dummyReqInst->setSquashed();
+ dummyReqInst->resetInstCount();
dummyBufferInst = new InOrderDynInst(this, NULL, 0, 0, 0);
dummyBufferInst->setSquashed();
+ dummyBufferInst->resetInstCount();
+
+ endOfSkedIt = skedCache.end();
lastRunningCycle = curTick();
@@ -348,7 +352,6 @@ InOrderCPU::InOrderCPU(Params *params)
reset();
#endif
- dummyBufferInst->resetInstCount();
// Schedule First Tick Event, CPU will reschedule itself from here on out.
scheduleTickEvent(0);
@@ -359,6 +362,7 @@ InOrderCPU::~InOrderCPU()
delete resPool;
}
+std::map<InOrderCPU::SkedID, ThePipeline::RSkedPtr> InOrderCPU::skedCache;
void
InOrderCPU::regStats()
diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh
index 9ff0f12ce..154ab690c 100644
--- a/src/cpu/inorder/cpu.hh
+++ b/src/cpu/inorder/cpu.hh
@@ -296,6 +296,62 @@ class InOrderCPU : public BaseCPU
TheISA::TLB *getITBPtr();
TheISA::TLB *getDTBPtr();
+ /** Accessor Type for the SkedCache */
+ typedef uint32_t SkedID;
+
+ /** Cache of Instruction Schedule using the instruction's name as a key */
+ static std::map<SkedID, ThePipeline::RSkedPtr> skedCache;
+
+ typedef std::map<SkedID, ThePipeline::RSkedPtr>::iterator SkedCacheIt;
+
+ /** Initialized to last iterator in map, signifying a invalid entry
+ on map searches
+ */
+ SkedCacheIt endOfSkedIt;
+
+ /** Add a new instruction schedule to the schedule cache */
+ void addToSkedCache(DynInstPtr inst, ThePipeline::RSkedPtr inst_sked)
+ {
+ SkedID sked_id = genSkedID(inst);
+ skedCache[sked_id] = inst_sked;
+ }
+
+
+ /** Find a instruction schedule */
+ ThePipeline::RSkedPtr lookupSked(DynInstPtr inst)
+ {
+ SkedID sked_id = genSkedID(inst);
+ SkedCacheIt lookup_it = skedCache.find(sked_id);
+
+ if (lookup_it != endOfSkedIt) {
+ return (*lookup_it).second;
+ } else {
+ return NULL;
+ }
+ }
+
+ static const uint8_t INST_OPCLASS = 26;
+ static const uint8_t INST_LOAD = 25;
+ static const uint8_t INST_STORE = 24;
+ static const uint8_t INST_CONTROL = 23;
+ static const uint8_t INST_NONSPEC = 22;
+ static const uint8_t INST_DEST_REGS = 18;
+ static const uint8_t INST_SRC_REGS = 14;
+
+ inline SkedID genSkedID(DynInstPtr inst)
+ {
+ SkedID id = 0;
+ id = (inst->opClass() << INST_OPCLASS) |
+ (inst->isLoad() << INST_LOAD) |
+ (inst->isStore() << INST_STORE) |
+ (inst->isControl() << INST_CONTROL) |
+ (inst->isNonSpeculative() << INST_NONSPEC) |
+ (inst->numDestRegs() << INST_DEST_REGS) |
+ (inst->numSrcRegs() << INST_SRC_REGS);
+ return id;
+ }
+
+
public:
/** Registers statistics. */
diff --git a/src/cpu/inorder/pipeline_traits.hh b/src/cpu/inorder/pipeline_traits.hh
index df964e254..2c4e44339 100644
--- a/src/cpu/inorder/pipeline_traits.hh
+++ b/src/cpu/inorder/pipeline_traits.hh
@@ -77,6 +77,7 @@ namespace ThePipeline {
// RESOURCE SCHEDULING
//////////////////////////
typedef ResourceSked ResSchedule;
+ typedef ResourceSked* RSkedPtr;
void createFrontEndSchedule(DynInstPtr &inst);
bool createBackEndSchedule(DynInstPtr &inst);