diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index bc718255aa..bc117b9aec 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -229,14 +229,14 @@ CPU::CPU(const BaseO3CPUParams ¶ms) ++ridx) { // Note that we can't use the rename() method because we don't // want special treatment for the zero register at this point - PhysRegIdPtr phys_reg = freeList.getIntReg(); + PhysRegIdPtr phys_reg = freeList.getReg(IntRegClass); renameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg); commitRenameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg); } for (RegIndex ridx = 0; ridx < regClasses.at(FloatRegClass).numRegs(); ++ridx) { - PhysRegIdPtr phys_reg = freeList.getFloatReg(); + PhysRegIdPtr phys_reg = freeList.getReg(FloatRegClass); renameMap[tid].setEntry(RegId(FloatRegClass, ridx), phys_reg); commitRenameMap[tid].setEntry( RegId(FloatRegClass, ridx), phys_reg); @@ -246,7 +246,7 @@ CPU::CPU(const BaseO3CPUParams ¶ms) /* Initialize the full-vector interface */ for (RegIndex ridx = 0; ridx < numVecs; ++ridx) { RegId rid = RegId(VecRegClass, ridx); - PhysRegIdPtr phys_reg = freeList.getVecReg(); + PhysRegIdPtr phys_reg = freeList.getReg(VecRegClass); renameMap[tid].setEntry(rid, phys_reg); commitRenameMap[tid].setEntry(rid, phys_reg); } @@ -254,14 +254,14 @@ CPU::CPU(const BaseO3CPUParams ¶ms) const size_t numElems = regClasses.at(VecElemClass).numRegs(); for (RegIndex ridx = 0; ridx < numElems; ++ridx) { RegId lrid = RegId(VecElemClass, ridx); - PhysRegIdPtr phys_elem = freeList.getVecElem(); + PhysRegIdPtr phys_elem = freeList.getReg(VecElemClass); renameMap[tid].setEntry(lrid, phys_elem); commitRenameMap[tid].setEntry(lrid, phys_elem); } for (RegIndex ridx = 0; ridx < regClasses.at(VecPredRegClass).numRegs(); ++ridx) { - PhysRegIdPtr phys_reg = freeList.getVecPredReg(); + PhysRegIdPtr phys_reg = freeList.getReg(VecPredRegClass); renameMap[tid].setEntry(RegId(VecPredRegClass, ridx), phys_reg); commitRenameMap[tid].setEntry( RegId(VecPredRegClass, ridx), phys_reg); @@ -269,7 +269,7 @@ CPU::CPU(const BaseO3CPUParams ¶ms) for (RegIndex ridx = 0; ridx < regClasses.at(CCRegClass).numRegs(); ++ridx) { - PhysRegIdPtr phys_reg = freeList.getCCReg(); + PhysRegIdPtr phys_reg = freeList.getReg(CCRegClass); renameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg); commitRenameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg); } @@ -730,7 +730,7 @@ CPU::insertThread(ThreadID tid) const auto ®Classes = isa[tid]->regClasses(); for (RegIndex idx = 0; idx < regClasses.at(IntRegClass).numRegs(); idx++) { - PhysRegIdPtr phys_reg = freeList.getIntReg(); + PhysRegIdPtr phys_reg = freeList.getReg(IntRegClass); renameMap[tid].setEntry(RegId(IntRegClass, idx), phys_reg); scoreboard.setReg(phys_reg); } @@ -738,14 +738,14 @@ CPU::insertThread(ThreadID tid) //Bind Float Regs to Rename Map for (RegIndex idx = 0; idx < regClasses.at(FloatRegClass).numRegs(); idx++) { - PhysRegIdPtr phys_reg = freeList.getFloatReg(); + PhysRegIdPtr phys_reg = freeList.getReg(FloatRegClass); renameMap[tid].setEntry(RegId(FloatRegClass, idx), phys_reg); scoreboard.setReg(phys_reg); } //Bind condition-code Regs to Rename Map for (RegIndex idx = 0; idx < regClasses.at(CCRegClass).numRegs(); idx++) { - PhysRegIdPtr phys_reg = freeList.getCCReg(); + PhysRegIdPtr phys_reg = freeList.getReg(CCRegClass); renameMap[tid].setEntry(RegId(CCRegClass, idx), phys_reg); scoreboard.setReg(phys_reg); } diff --git a/src/cpu/o3/free_list.hh b/src/cpu/o3/free_list.hh index 54edfc1ab6..408d6e06ab 100644 --- a/src/cpu/o3/free_list.hh +++ b/src/cpu/o3/free_list.hh @@ -42,6 +42,8 @@ #ifndef __CPU_O3_FREE_LIST_HH__ #define __CPU_O3_FREE_LIST_HH__ +#include +#include #include #include @@ -127,26 +129,7 @@ class UnifiedFreeList * explicitly because Scoreboard is not a SimObject. */ const std::string _name; - /** The list of free integer registers. */ - SimpleFreeList intList; - - /** The list of free floating point registers. */ - SimpleFreeList floatList; - - /** The following two are exclusive interfaces. */ - /** @{ */ - /** The list of free vector registers. */ - SimpleFreeList vecList; - - /** The list of free vector element registers. */ - SimpleFreeList vecElemList; - /** @} */ - - /** The list of free predicate registers. */ - SimpleFreeList predList; - - /** The list of free condition-code registers. */ - SimpleFreeList ccList; + std::array freeLists; /** * The register file object is used only to distinguish integer @@ -175,174 +158,39 @@ class UnifiedFreeList /** Gives the name of the freelist. */ std::string name() const { return _name; }; - /** Returns a pointer to the condition-code free list */ - SimpleFreeList *getCCList() { return &ccList; } - - /** Gets a free integer register. */ - PhysRegIdPtr getIntReg() { return intList.getReg(); } - - /** Gets a free fp register. */ - PhysRegIdPtr getFloatReg() { return floatList.getReg(); } - - /** Gets a free vector register. */ - PhysRegIdPtr getVecReg() { return vecList.getReg(); } - - /** Gets a free vector elemenet register. */ - PhysRegIdPtr getVecElem() { return vecElemList.getReg(); } - - /** Gets a free predicate register. */ - PhysRegIdPtr getVecPredReg() { return predList.getReg(); } - - /** Gets a free cc register. */ - PhysRegIdPtr getCCReg() { return ccList.getReg(); } - - /** Adds a register back to the free list. */ - void addReg(PhysRegIdPtr freed_reg); + /** Gets a free register of type type. */ + PhysRegIdPtr getReg(RegClassType type) { return freeLists[type].getReg(); } /** Adds a register back to the free list. */ template - void addRegs(InputIt first, InputIt last); - - /** Adds an integer register back to the free list. */ - void addIntReg(PhysRegIdPtr freed_reg) { intList.addReg(freed_reg); } - - /** Adds a fp register back to the free list. */ - void addFloatReg(PhysRegIdPtr freed_reg) { floatList.addReg(freed_reg); } - - /** Adds a vector register back to the free list. */ - void addVecReg(PhysRegIdPtr freed_reg) { vecList.addReg(freed_reg); } - - /** Adds a vector element register back to the free list. */ - void addVecElem(PhysRegIdPtr freed_reg) { - vecElemList.addReg(freed_reg); + void + addRegs(InputIt first, InputIt last) + { + std::for_each(first, last, [this](auto ®) { addReg(®); }); } - /** Adds a predicate register back to the free list. */ - void addVecPredReg(PhysRegIdPtr freed_reg) { predList.addReg(freed_reg); } + /** Adds a register back to the free list. */ + void + addReg(PhysRegIdPtr freed_reg) + { + freeLists[freed_reg->classValue()].addReg(freed_reg); + } - /** Adds a cc register back to the free list. */ - void addCCReg(PhysRegIdPtr freed_reg) { ccList.addReg(freed_reg); } + /** Checks if there are any free registers of type type. */ + bool + hasFreeRegs(RegClassType type) const + { + return freeLists[type].hasFreeRegs(); + } - /** Checks if there are any free integer registers. */ - bool hasFreeIntRegs() const { return intList.hasFreeRegs(); } - - /** Checks if there are any free fp registers. */ - bool hasFreeFloatRegs() const { return floatList.hasFreeRegs(); } - - /** Checks if there are any free vector registers. */ - bool hasFreeVecRegs() const { return vecList.hasFreeRegs(); } - - /** Checks if there are any free vector registers. */ - bool hasFreeVecElems() const { return vecElemList.hasFreeRegs(); } - - /** Checks if there are any free predicate registers. */ - bool hasFreeVecPredRegs() const { return predList.hasFreeRegs(); } - - /** Checks if there are any free cc registers. */ - bool hasFreeCCRegs() const { return ccList.hasFreeRegs(); } - - /** Returns the number of free integer registers. */ - unsigned numFreeIntRegs() const { return intList.numFreeRegs(); } - - /** Returns the number of free fp registers. */ - unsigned numFreeFloatRegs() const { return floatList.numFreeRegs(); } - - /** Returns the number of free vector registers. */ - unsigned numFreeVecRegs() const { return vecList.numFreeRegs(); } - - /** Returns the number of free vector registers. */ - unsigned numFreeVecElems() const { return vecElemList.numFreeRegs(); } - - /** Returns the number of free predicate registers. */ - unsigned numFreeVecPredRegs() const { return predList.numFreeRegs(); } - - /** Returns the number of free cc registers. */ - unsigned numFreeCCRegs() const { return ccList.numFreeRegs(); } + /** Returns the number of free registers of type type. */ + unsigned + numFreeRegs(RegClassType type) const + { + return freeLists[type].numFreeRegs(); + } }; -template -inline void -UnifiedFreeList::addRegs(InputIt first, InputIt last) -{ - // Are there any registers to add? - if (first == last) - return; - - panic_if((first != last) && - first->classValue() != (last-1)->classValue(), - "Attempt to add mixed type regs: %s and %s", - first->className(), - (last-1)->className()); - switch (first->classValue()) { - case IntRegClass: - intList.addRegs(first, last); - break; - case FloatRegClass: - floatList.addRegs(first, last); - break; - case VecRegClass: - vecList.addRegs(first, last); - break; - case VecElemClass: - vecElemList.addRegs(first, last); - break; - case VecPredRegClass: - predList.addRegs(first, last); - break; - case CCRegClass: - ccList.addRegs(first, last); - break; - default: - panic("Unexpected RegClass (%s)", - first->className()); - } - -} - -inline void -UnifiedFreeList::addReg(PhysRegIdPtr freed_reg) -{ - DPRINTF(FreeList,"Freeing register %i (%s).\n", freed_reg->index(), - freed_reg->className()); - //Might want to add in a check for whether or not this register is - //already in there. A bit vector or something similar would be useful. - switch (freed_reg->classValue()) { - case IntRegClass: - intList.addReg(freed_reg); - break; - case FloatRegClass: - floatList.addReg(freed_reg); - break; - case VecRegClass: - vecList.addReg(freed_reg); - break; - case VecElemClass: - vecElemList.addReg(freed_reg); - break; - case VecPredRegClass: - predList.addReg(freed_reg); - break; - case CCRegClass: - ccList.addReg(freed_reg); - break; - default: - panic("Unexpected RegClass (%s)", - freed_reg->className()); - } - - // These assert conditions ensure that the number of free - // registers are not more than the # of total Physical Registers. - // If this were false, it would mean that registers - // have been freed twice, overflowing the free register - // pool and potentially crashing SMT workloads. - // ---- - // Comment out for now so as to not potentially break - // CMP and single-threaded workloads - // ---- - // assert(freeIntRegs.size() <= numPhysicalIntRegs); - // assert(freeFloatRegs.size() <= numPhysicalFloatRegs); -} - } // namespace o3 } // namespace gem5 diff --git a/src/cpu/o3/rename_map.cc b/src/cpu/o3/rename_map.cc index d665b6a59b..256b4bf354 100644 --- a/src/cpu/o3/rename_map.cc +++ b/src/cpu/o3/rename_map.cc @@ -115,18 +115,8 @@ UnifiedRenameMap::init(const BaseISA::RegClasses ®Classes, { regFile = _regFile; - renameMaps[IntRegClass].init(regClasses.at(IntRegClass), - &(freeList->intList)); - renameMaps[FloatRegClass].init(regClasses.at(FloatRegClass), - &(freeList->floatList)); - renameMaps[VecRegClass].init(regClasses.at(VecRegClass), - &(freeList->vecList)); - renameMaps[VecElemClass].init(regClasses.at(VecElemClass), - &(freeList->vecElemList)); - renameMaps[VecPredRegClass].init(regClasses.at(VecPredRegClass), - &(freeList->predList)); - renameMaps[CCRegClass].init(regClasses.at(CCRegClass), - &(freeList->ccList)); + for (int i = 0; i < renameMaps.size(); i++) + renameMaps[i].init(regClasses.at(i), &(freeList->freeLists[i])); } bool