free_list.hh revision 12109
11689SN/A/* 212109SRekai.GonzalezAlberquilla@arm.com * Copyright (c) 2016 ARM Limited 312109SRekai.GonzalezAlberquilla@arm.com * All rights reserved 412109SRekai.GonzalezAlberquilla@arm.com * 512109SRekai.GonzalezAlberquilla@arm.com * The license below extends only to copyright in the software and shall 612109SRekai.GonzalezAlberquilla@arm.com * not be construed as granting a license to any other intellectual 712109SRekai.GonzalezAlberquilla@arm.com * property including but not limited to intellectual property relating 812109SRekai.GonzalezAlberquilla@arm.com * to a hardware implementation of the functionality of the software 912109SRekai.GonzalezAlberquilla@arm.com * licensed hereunder. You may use the software subject to the license 1012109SRekai.GonzalezAlberquilla@arm.com * terms below provided that you ensure that this notice is replicated 1112109SRekai.GonzalezAlberquilla@arm.com * unmodified and in its entirety in all distributions of the software, 1212109SRekai.GonzalezAlberquilla@arm.com * modified or unmodified, in source code or in binary form. 1312109SRekai.GonzalezAlberquilla@arm.com * 141689SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 159919Ssteve.reinhardt@amd.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 161689SN/A * All rights reserved. 171689SN/A * 181689SN/A * Redistribution and use in source and binary forms, with or without 191689SN/A * modification, are permitted provided that the following conditions are 201689SN/A * met: redistributions of source code must retain the above copyright 211689SN/A * notice, this list of conditions and the following disclaimer; 221689SN/A * redistributions in binary form must reproduce the above copyright 231689SN/A * notice, this list of conditions and the following disclaimer in the 241689SN/A * documentation and/or other materials provided with the distribution; 251689SN/A * neither the name of the copyright holders nor the names of its 261689SN/A * contributors may be used to endorse or promote products derived from 271689SN/A * this software without specific prior written permission. 281689SN/A * 291689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 301689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 311689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 321689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 331689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 341689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 351689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 361689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 371689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 381689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 391689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402665Ssaidi@eecs.umich.edu * 412665Ssaidi@eecs.umich.edu * Authors: Kevin Lim 421689SN/A */ 431689SN/A 442292SN/A#ifndef __CPU_O3_FREE_LIST_HH__ 452292SN/A#define __CPU_O3_FREE_LIST_HH__ 461060SN/A 471060SN/A#include <iostream> 481060SN/A#include <queue> 4912105Snathanael.premillieu@arm.com#include <vector> 501060SN/A 512669Sktlim@umich.edu#include "base/misc.hh" 521684SN/A#include "base/trace.hh" 531717SN/A#include "cpu/o3/comm.hh" 549919Ssteve.reinhardt@amd.com#include "cpu/o3/regfile.hh" 558232Snate@binkert.org#include "debug/FreeList.hh" 561060SN/A 571060SN/A/** 589919Ssteve.reinhardt@amd.com * Free list for a single class of registers (e.g., integer 599919Ssteve.reinhardt@amd.com * or floating point). Because the register class is implicitly 609919Ssteve.reinhardt@amd.com * determined by the rename map instance being accessed, all 619919Ssteve.reinhardt@amd.com * architectural register index parameters and values in this class 629919Ssteve.reinhardt@amd.com * are relative (e.g., %fp2 is just index 2). 639919Ssteve.reinhardt@amd.com */ 649919Ssteve.reinhardt@amd.comclass SimpleFreeList 659919Ssteve.reinhardt@amd.com{ 669919Ssteve.reinhardt@amd.com private: 679919Ssteve.reinhardt@amd.com 689919Ssteve.reinhardt@amd.com /** The actual free list */ 6912105Snathanael.premillieu@arm.com std::queue<PhysRegIdPtr> freeRegs; 709919Ssteve.reinhardt@amd.com 719919Ssteve.reinhardt@amd.com public: 729919Ssteve.reinhardt@amd.com 739919Ssteve.reinhardt@amd.com SimpleFreeList() {}; 749919Ssteve.reinhardt@amd.com 759919Ssteve.reinhardt@amd.com /** Add a physical register to the free list */ 7612105Snathanael.premillieu@arm.com void addReg(PhysRegIdPtr reg) { freeRegs.push(reg); } 779919Ssteve.reinhardt@amd.com 7812109SRekai.GonzalezAlberquilla@arm.com /** Add physical registers to the free list */ 7912109SRekai.GonzalezAlberquilla@arm.com template<class InputIt> 8012109SRekai.GonzalezAlberquilla@arm.com void 8112109SRekai.GonzalezAlberquilla@arm.com addRegs(InputIt first, InputIt last) { 8212109SRekai.GonzalezAlberquilla@arm.com std::for_each(first, last, 8312109SRekai.GonzalezAlberquilla@arm.com [this](const typename InputIt::value_type& reg) { 8412109SRekai.GonzalezAlberquilla@arm.com this->freeRegs.push(®); 8512109SRekai.GonzalezAlberquilla@arm.com }); 8612109SRekai.GonzalezAlberquilla@arm.com } 8712109SRekai.GonzalezAlberquilla@arm.com 889919Ssteve.reinhardt@amd.com /** Get the next available register from the free list */ 8912105Snathanael.premillieu@arm.com PhysRegIdPtr getReg() 909919Ssteve.reinhardt@amd.com { 919919Ssteve.reinhardt@amd.com assert(!freeRegs.empty()); 9212105Snathanael.premillieu@arm.com PhysRegIdPtr free_reg = freeRegs.front(); 939919Ssteve.reinhardt@amd.com freeRegs.pop(); 949919Ssteve.reinhardt@amd.com return free_reg; 959919Ssteve.reinhardt@amd.com } 969919Ssteve.reinhardt@amd.com 979919Ssteve.reinhardt@amd.com /** Return the number of free registers on the list. */ 989919Ssteve.reinhardt@amd.com unsigned numFreeRegs() const { return freeRegs.size(); } 999919Ssteve.reinhardt@amd.com 1009919Ssteve.reinhardt@amd.com /** True iff there are free registers on the list. */ 1019919Ssteve.reinhardt@amd.com bool hasFreeRegs() const { return !freeRegs.empty(); } 1029919Ssteve.reinhardt@amd.com}; 1039919Ssteve.reinhardt@amd.com 1049919Ssteve.reinhardt@amd.com 1059919Ssteve.reinhardt@amd.com/** 1061060SN/A * FreeList class that simply holds the list of free integer and floating 1071060SN/A * point registers. Can request for a free register of either type, and 1081060SN/A * also send back free registers of either type. This is a very simple 1091060SN/A * class, but it should be sufficient for most implementations. Like all 1101060SN/A * other classes, it assumes that the indices for the floating point 1111060SN/A * registers starts after the integer registers end. Hence the variable 1121060SN/A * numPhysicalIntRegs is logically equivalent to the baseFP dependency. 1132292SN/A * Note that while this most likely should be called FreeList, the name 1142292SN/A * "FreeList" is used in a typedef within the CPU Policy, and therefore no 1152292SN/A * class can be named simply "FreeList". 1161060SN/A * @todo: Give a better name to the base FP dependency. 1171060SN/A */ 1189919Ssteve.reinhardt@amd.comclass UnifiedFreeList 1191060SN/A{ 1201060SN/A private: 1219919Ssteve.reinhardt@amd.com 1229919Ssteve.reinhardt@amd.com /** The object name, for DPRINTF. We have to declare this 1239919Ssteve.reinhardt@amd.com * explicitly because Scoreboard is not a SimObject. */ 1249919Ssteve.reinhardt@amd.com const std::string _name; 1259919Ssteve.reinhardt@amd.com 1261060SN/A /** The list of free integer registers. */ 1279919Ssteve.reinhardt@amd.com SimpleFreeList intList; 1281060SN/A 1291060SN/A /** The list of free floating point registers. */ 1309919Ssteve.reinhardt@amd.com SimpleFreeList floatList; 1311060SN/A 13212109SRekai.GonzalezAlberquilla@arm.com /** The following two are exclusive interfaces. */ 13312109SRekai.GonzalezAlberquilla@arm.com /** @{ */ 13412109SRekai.GonzalezAlberquilla@arm.com /** The list of free vector registers. */ 13512109SRekai.GonzalezAlberquilla@arm.com SimpleFreeList vecList; 13612109SRekai.GonzalezAlberquilla@arm.com 13712109SRekai.GonzalezAlberquilla@arm.com /** The list of free vector element registers. */ 13812109SRekai.GonzalezAlberquilla@arm.com SimpleFreeList vecElemList; 13912109SRekai.GonzalezAlberquilla@arm.com /** @} */ 14012109SRekai.GonzalezAlberquilla@arm.com 1419920Syasuko.eckert@amd.com /** The list of free condition-code registers. */ 1429920Syasuko.eckert@amd.com SimpleFreeList ccList; 1439920Syasuko.eckert@amd.com 1449919Ssteve.reinhardt@amd.com /** 1459919Ssteve.reinhardt@amd.com * The register file object is used only to distinguish integer 1469919Ssteve.reinhardt@amd.com * from floating-point physical register indices. 1479919Ssteve.reinhardt@amd.com */ 1489919Ssteve.reinhardt@amd.com PhysRegFile *regFile; 1491060SN/A 1509919Ssteve.reinhardt@amd.com /* 1519919Ssteve.reinhardt@amd.com * We give UnifiedRenameMap internal access so it can get at the 1529919Ssteve.reinhardt@amd.com * internal per-class free lists and associate those with its 1539919Ssteve.reinhardt@amd.com * per-class rename maps. See UnifiedRenameMap::init(). 1549919Ssteve.reinhardt@amd.com */ 1559919Ssteve.reinhardt@amd.com friend class UnifiedRenameMap; 1561060SN/A 1571060SN/A public: 1582292SN/A /** Constructs a free list. 1592292SN/A * @param _numPhysicalIntRegs Number of physical integer registers. 1609919Ssteve.reinhardt@amd.com * @param reservedIntRegs Number of integer registers already 1619919Ssteve.reinhardt@amd.com * used by initial mappings. 1622292SN/A * @param _numPhysicalFloatRegs Number of physical fp registers. 1639919Ssteve.reinhardt@amd.com * @param reservedFloatRegs Number of fp registers already 1649919Ssteve.reinhardt@amd.com * used by initial mappings. 1652292SN/A */ 1669919Ssteve.reinhardt@amd.com UnifiedFreeList(const std::string &_my_name, PhysRegFile *_regFile); 1671060SN/A 1682292SN/A /** Gives the name of the freelist. */ 1699919Ssteve.reinhardt@amd.com std::string name() const { return _name; }; 1702292SN/A 1719920Syasuko.eckert@amd.com /** Returns a pointer to the condition-code free list */ 1729920Syasuko.eckert@amd.com SimpleFreeList *getCCList() { return &ccList; } 1739920Syasuko.eckert@amd.com 1742292SN/A /** Gets a free integer register. */ 17512105Snathanael.premillieu@arm.com PhysRegIdPtr getIntReg() { return intList.getReg(); } 1761060SN/A 1772292SN/A /** Gets a free fp register. */ 17812105Snathanael.premillieu@arm.com PhysRegIdPtr getFloatReg() { return floatList.getReg(); } 1791060SN/A 18012109SRekai.GonzalezAlberquilla@arm.com /** Gets a free vector register. */ 18112109SRekai.GonzalezAlberquilla@arm.com PhysRegIdPtr getVecReg() { return vecList.getReg(); } 18212109SRekai.GonzalezAlberquilla@arm.com 18312109SRekai.GonzalezAlberquilla@arm.com /** Gets a free vector elemenet register. */ 18412109SRekai.GonzalezAlberquilla@arm.com PhysRegIdPtr getVecElem() { return vecElemList.getReg(); } 18512109SRekai.GonzalezAlberquilla@arm.com 1869920Syasuko.eckert@amd.com /** Gets a free cc register. */ 18712105Snathanael.premillieu@arm.com PhysRegIdPtr getCCReg() { return ccList.getReg(); } 1889920Syasuko.eckert@amd.com 1892292SN/A /** Adds a register back to the free list. */ 19012105Snathanael.premillieu@arm.com void addReg(PhysRegIdPtr freed_reg); 1911060SN/A 19212109SRekai.GonzalezAlberquilla@arm.com /** Adds a register back to the free list. */ 19312109SRekai.GonzalezAlberquilla@arm.com template<class InputIt> 19412109SRekai.GonzalezAlberquilla@arm.com void addRegs(InputIt first, InputIt last); 19512109SRekai.GonzalezAlberquilla@arm.com 1962292SN/A /** Adds an integer register back to the free list. */ 19712105Snathanael.premillieu@arm.com void addIntReg(PhysRegIdPtr freed_reg) { intList.addReg(freed_reg); } 1981060SN/A 1992292SN/A /** Adds a fp register back to the free list. */ 20012105Snathanael.premillieu@arm.com void addFloatReg(PhysRegIdPtr freed_reg) { floatList.addReg(freed_reg); } 2011060SN/A 20212109SRekai.GonzalezAlberquilla@arm.com /** Adds a vector register back to the free list. */ 20312109SRekai.GonzalezAlberquilla@arm.com void addVecReg(PhysRegIdPtr freed_reg) { vecList.addReg(freed_reg); } 20412109SRekai.GonzalezAlberquilla@arm.com 20512109SRekai.GonzalezAlberquilla@arm.com /** Adds a vector element register back to the free list. */ 20612109SRekai.GonzalezAlberquilla@arm.com void addVecElem(PhysRegIdPtr freed_reg) { 20712109SRekai.GonzalezAlberquilla@arm.com vecElemList.addReg(freed_reg); 20812109SRekai.GonzalezAlberquilla@arm.com } 20912109SRekai.GonzalezAlberquilla@arm.com 2109920Syasuko.eckert@amd.com /** Adds a cc register back to the free list. */ 21112105Snathanael.premillieu@arm.com void addCCReg(PhysRegIdPtr freed_reg) { ccList.addReg(freed_reg); } 2129920Syasuko.eckert@amd.com 2132292SN/A /** Checks if there are any free integer registers. */ 2149919Ssteve.reinhardt@amd.com bool hasFreeIntRegs() const { return intList.hasFreeRegs(); } 2151060SN/A 2162292SN/A /** Checks if there are any free fp registers. */ 2179919Ssteve.reinhardt@amd.com bool hasFreeFloatRegs() const { return floatList.hasFreeRegs(); } 2181060SN/A 21912109SRekai.GonzalezAlberquilla@arm.com /** Checks if there are any free vector registers. */ 22012109SRekai.GonzalezAlberquilla@arm.com bool hasFreeVecRegs() const { return vecList.hasFreeRegs(); } 22112109SRekai.GonzalezAlberquilla@arm.com 22212109SRekai.GonzalezAlberquilla@arm.com /** Checks if there are any free vector registers. */ 22312109SRekai.GonzalezAlberquilla@arm.com bool hasFreeVecElems() const { return vecElemList.hasFreeRegs(); } 22412109SRekai.GonzalezAlberquilla@arm.com 2259920Syasuko.eckert@amd.com /** Checks if there are any free cc registers. */ 2269920Syasuko.eckert@amd.com bool hasFreeCCRegs() const { return ccList.hasFreeRegs(); } 2279920Syasuko.eckert@amd.com 2282292SN/A /** Returns the number of free integer registers. */ 2299919Ssteve.reinhardt@amd.com unsigned numFreeIntRegs() const { return intList.numFreeRegs(); } 2301060SN/A 2312292SN/A /** Returns the number of free fp registers. */ 2329919Ssteve.reinhardt@amd.com unsigned numFreeFloatRegs() const { return floatList.numFreeRegs(); } 2339920Syasuko.eckert@amd.com 23412109SRekai.GonzalezAlberquilla@arm.com /** Returns the number of free vector registers. */ 23512109SRekai.GonzalezAlberquilla@arm.com unsigned numFreeVecRegs() const { return vecList.numFreeRegs(); } 23612109SRekai.GonzalezAlberquilla@arm.com 2379920Syasuko.eckert@amd.com /** Returns the number of free cc registers. */ 2389920Syasuko.eckert@amd.com unsigned numFreeCCRegs() const { return ccList.numFreeRegs(); } 2391060SN/A}; 2401060SN/A 24112109SRekai.GonzalezAlberquilla@arm.comtemplate<class InputIt> 24212109SRekai.GonzalezAlberquilla@arm.cominline void 24312109SRekai.GonzalezAlberquilla@arm.comUnifiedFreeList::addRegs(InputIt first, InputIt last) 24412109SRekai.GonzalezAlberquilla@arm.com{ 24512109SRekai.GonzalezAlberquilla@arm.com // Are there any registers to add? 24612109SRekai.GonzalezAlberquilla@arm.com if (first == last) 24712109SRekai.GonzalezAlberquilla@arm.com return; 24812109SRekai.GonzalezAlberquilla@arm.com 24912109SRekai.GonzalezAlberquilla@arm.com panic_if((first != last) && 25012109SRekai.GonzalezAlberquilla@arm.com first->classValue() != (last-1)->classValue(), 25112109SRekai.GonzalezAlberquilla@arm.com "Attempt to add mixed type regs: %s and %s", 25212109SRekai.GonzalezAlberquilla@arm.com first->className(), 25312109SRekai.GonzalezAlberquilla@arm.com (last-1)->className()); 25412109SRekai.GonzalezAlberquilla@arm.com switch (first->classValue()) { 25512109SRekai.GonzalezAlberquilla@arm.com case IntRegClass: 25612109SRekai.GonzalezAlberquilla@arm.com intList.addRegs(first, last); 25712109SRekai.GonzalezAlberquilla@arm.com break; 25812109SRekai.GonzalezAlberquilla@arm.com case FloatRegClass: 25912109SRekai.GonzalezAlberquilla@arm.com floatList.addRegs(first, last); 26012109SRekai.GonzalezAlberquilla@arm.com break; 26112109SRekai.GonzalezAlberquilla@arm.com case VecRegClass: 26212109SRekai.GonzalezAlberquilla@arm.com vecList.addRegs(first, last); 26312109SRekai.GonzalezAlberquilla@arm.com break; 26412109SRekai.GonzalezAlberquilla@arm.com case VecElemClass: 26512109SRekai.GonzalezAlberquilla@arm.com vecElemList.addRegs(first, last); 26612109SRekai.GonzalezAlberquilla@arm.com break; 26712109SRekai.GonzalezAlberquilla@arm.com case CCRegClass: 26812109SRekai.GonzalezAlberquilla@arm.com ccList.addRegs(first, last); 26912109SRekai.GonzalezAlberquilla@arm.com break; 27012109SRekai.GonzalezAlberquilla@arm.com default: 27112109SRekai.GonzalezAlberquilla@arm.com panic("Unexpected RegClass (%s)", 27212109SRekai.GonzalezAlberquilla@arm.com first->className()); 27312109SRekai.GonzalezAlberquilla@arm.com } 27412109SRekai.GonzalezAlberquilla@arm.com 27512109SRekai.GonzalezAlberquilla@arm.com} 27612109SRekai.GonzalezAlberquilla@arm.com 2771060SN/Ainline void 27812105Snathanael.premillieu@arm.comUnifiedFreeList::addReg(PhysRegIdPtr freed_reg) 2791060SN/A{ 28012106SRekai.GonzalezAlberquilla@arm.com DPRINTF(FreeList,"Freeing register %i (%s).\n", freed_reg->index(), 28112106SRekai.GonzalezAlberquilla@arm.com freed_reg->className()); 2821060SN/A //Might want to add in a check for whether or not this register is 2831060SN/A //already in there. A bit vector or something similar would be useful. 28412106SRekai.GonzalezAlberquilla@arm.com switch (freed_reg->classValue()) { 28512105Snathanael.premillieu@arm.com case IntRegClass: 28612105Snathanael.premillieu@arm.com intList.addReg(freed_reg); 28712105Snathanael.premillieu@arm.com break; 28812105Snathanael.premillieu@arm.com case FloatRegClass: 28912105Snathanael.premillieu@arm.com floatList.addReg(freed_reg); 29012105Snathanael.premillieu@arm.com break; 29112109SRekai.GonzalezAlberquilla@arm.com case VecRegClass: 29212109SRekai.GonzalezAlberquilla@arm.com vecList.addReg(freed_reg); 29312109SRekai.GonzalezAlberquilla@arm.com break; 29412109SRekai.GonzalezAlberquilla@arm.com case VecElemClass: 29512109SRekai.GonzalezAlberquilla@arm.com vecElemList.addReg(freed_reg); 29612109SRekai.GonzalezAlberquilla@arm.com break; 29712105Snathanael.premillieu@arm.com case CCRegClass: 29812105Snathanael.premillieu@arm.com ccList.addReg(freed_reg); 29912105Snathanael.premillieu@arm.com break; 30012105Snathanael.premillieu@arm.com default: 30112105Snathanael.premillieu@arm.com panic("Unexpected RegClass (%s)", 30212106SRekai.GonzalezAlberquilla@arm.com freed_reg->className()); 3031060SN/A } 3045362Sksewell@umich.edu 3055364Sksewell@umich.edu // These assert conditions ensure that the number of free 3065364Sksewell@umich.edu // registers are not more than the # of total Physical Registers. 3075364Sksewell@umich.edu // If this were false, it would mean that registers 3085364Sksewell@umich.edu // have been freed twice, overflowing the free register 3095364Sksewell@umich.edu // pool and potentially crashing SMT workloads. 3105364Sksewell@umich.edu // ---- 3115364Sksewell@umich.edu // Comment out for now so as to not potentially break 3125364Sksewell@umich.edu // CMP and single-threaded workloads 3135364Sksewell@umich.edu // ---- 3145364Sksewell@umich.edu // assert(freeIntRegs.size() <= numPhysicalIntRegs); 3155364Sksewell@umich.edu // assert(freeFloatRegs.size() <= numPhysicalFloatRegs); 3161060SN/A} 3171060SN/A 3181060SN/A 3192292SN/A#endif // __CPU_O3_FREE_LIST_HH__ 320