free_list.hh revision 12334
112150Sgabor.dozsa@arm.com/* 212150Sgabor.dozsa@arm.com * Copyright (c) 2016 ARM Limited 312150Sgabor.dozsa@arm.com * All rights reserved 412150Sgabor.dozsa@arm.com * 512150Sgabor.dozsa@arm.com * The license below extends only to copyright in the software and shall 612150Sgabor.dozsa@arm.com * not be construed as granting a license to any other intellectual 712150Sgabor.dozsa@arm.com * property including but not limited to intellectual property relating 812150Sgabor.dozsa@arm.com * to a hardware implementation of the functionality of the software 912150Sgabor.dozsa@arm.com * licensed hereunder. You may use the software subject to the license 1012150Sgabor.dozsa@arm.com * terms below provided that you ensure that this notice is replicated 1112150Sgabor.dozsa@arm.com * unmodified and in its entirety in all distributions of the software, 1212150Sgabor.dozsa@arm.com * modified or unmodified, in source code or in binary form. 1312150Sgabor.dozsa@arm.com * 1412150Sgabor.dozsa@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 1512150Sgabor.dozsa@arm.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 1612150Sgabor.dozsa@arm.com * All rights reserved. 1712150Sgabor.dozsa@arm.com * 1812150Sgabor.dozsa@arm.com * Redistribution and use in source and binary forms, with or without 1912150Sgabor.dozsa@arm.com * modification, are permitted provided that the following conditions are 2012150Sgabor.dozsa@arm.com * met: redistributions of source code must retain the above copyright 2112150Sgabor.dozsa@arm.com * notice, this list of conditions and the following disclaimer; 2212150Sgabor.dozsa@arm.com * redistributions in binary form must reproduce the above copyright 2312150Sgabor.dozsa@arm.com * notice, this list of conditions and the following disclaimer in the 2412150Sgabor.dozsa@arm.com * documentation and/or other materials provided with the distribution; 2512150Sgabor.dozsa@arm.com * neither the name of the copyright holders nor the names of its 2612150Sgabor.dozsa@arm.com * contributors may be used to endorse or promote products derived from 2712150Sgabor.dozsa@arm.com * this software without specific prior written permission. 2812150Sgabor.dozsa@arm.com * 2912150Sgabor.dozsa@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3012150Sgabor.dozsa@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3112150Sgabor.dozsa@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3212150Sgabor.dozsa@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3312150Sgabor.dozsa@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3412150Sgabor.dozsa@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3512150Sgabor.dozsa@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3612150Sgabor.dozsa@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3712150Sgabor.dozsa@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3812150Sgabor.dozsa@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3912150Sgabor.dozsa@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4012150Sgabor.dozsa@arm.com * 4112150Sgabor.dozsa@arm.com * Authors: Kevin Lim 4212150Sgabor.dozsa@arm.com */ 4312150Sgabor.dozsa@arm.com 4412150Sgabor.dozsa@arm.com#ifndef __CPU_O3_FREE_LIST_HH__ 4512150Sgabor.dozsa@arm.com#define __CPU_O3_FREE_LIST_HH__ 4612564Sgabeblack@google.com 4712564Sgabeblack@google.com#include <iostream> 4812150Sgabor.dozsa@arm.com#include <queue> 4912150Sgabor.dozsa@arm.com#include <vector> 5012150Sgabor.dozsa@arm.com 5112150Sgabor.dozsa@arm.com#include "base/logging.hh" 5213609Sgiacomo.travaglini@arm.com#include "base/trace.hh" 5312150Sgabor.dozsa@arm.com#include "cpu/o3/comm.hh" 5412150Sgabor.dozsa@arm.com#include "cpu/o3/regfile.hh" 5512150Sgabor.dozsa@arm.com#include "debug/FreeList.hh" 5612150Sgabor.dozsa@arm.com 5712150Sgabor.dozsa@arm.com/** 5812150Sgabor.dozsa@arm.com * Free list for a single class of registers (e.g., integer 5912150Sgabor.dozsa@arm.com * or floating point). Because the register class is implicitly 6012150Sgabor.dozsa@arm.com * determined by the rename map instance being accessed, all 6112150Sgabor.dozsa@arm.com * architectural register index parameters and values in this class 6212150Sgabor.dozsa@arm.com * are relative (e.g., %fp2 is just index 2). 6312150Sgabor.dozsa@arm.com */ 6412150Sgabor.dozsa@arm.comclass SimpleFreeList 6512150Sgabor.dozsa@arm.com{ 6612150Sgabor.dozsa@arm.com private: 6712150Sgabor.dozsa@arm.com 6812150Sgabor.dozsa@arm.com /** The actual free list */ 6912150Sgabor.dozsa@arm.com std::queue<PhysRegIdPtr> freeRegs; 7012150Sgabor.dozsa@arm.com 7112150Sgabor.dozsa@arm.com public: 7212150Sgabor.dozsa@arm.com 7312150Sgabor.dozsa@arm.com SimpleFreeList() {}; 7412150Sgabor.dozsa@arm.com 7512150Sgabor.dozsa@arm.com /** Add a physical register to the free list */ 7612150Sgabor.dozsa@arm.com void addReg(PhysRegIdPtr reg) { freeRegs.push(reg); } 7712150Sgabor.dozsa@arm.com 7812150Sgabor.dozsa@arm.com /** Add physical registers to the free list */ 7912150Sgabor.dozsa@arm.com template<class InputIt> 8012150Sgabor.dozsa@arm.com void 8112150Sgabor.dozsa@arm.com addRegs(InputIt first, InputIt last) { 8212150Sgabor.dozsa@arm.com std::for_each(first, last, 8312150Sgabor.dozsa@arm.com [this](const typename InputIt::value_type& reg) { 8412150Sgabor.dozsa@arm.com this->freeRegs.push(®); 8512150Sgabor.dozsa@arm.com }); 8612150Sgabor.dozsa@arm.com } 8712150Sgabor.dozsa@arm.com 8812150Sgabor.dozsa@arm.com /** Get the next available register from the free list */ 8912150Sgabor.dozsa@arm.com PhysRegIdPtr getReg() 9012150Sgabor.dozsa@arm.com { 9112150Sgabor.dozsa@arm.com assert(!freeRegs.empty()); 9212150Sgabor.dozsa@arm.com PhysRegIdPtr free_reg = freeRegs.front(); 9312150Sgabor.dozsa@arm.com freeRegs.pop(); 9412150Sgabor.dozsa@arm.com return free_reg; 9512150Sgabor.dozsa@arm.com } 9612150Sgabor.dozsa@arm.com 9712564Sgabeblack@google.com /** Return the number of free registers on the list. */ 9812150Sgabor.dozsa@arm.com unsigned numFreeRegs() const { return freeRegs.size(); } 9912150Sgabor.dozsa@arm.com 10012150Sgabor.dozsa@arm.com /** True iff there are free registers on the list. */ 10112150Sgabor.dozsa@arm.com bool hasFreeRegs() const { return !freeRegs.empty(); } 10212150Sgabor.dozsa@arm.com}; 10312150Sgabor.dozsa@arm.com 10412150Sgabor.dozsa@arm.com 10512150Sgabor.dozsa@arm.com/** 10612150Sgabor.dozsa@arm.com * FreeList class that simply holds the list of free integer and floating 10712150Sgabor.dozsa@arm.com * point registers. Can request for a free register of either type, and 10812150Sgabor.dozsa@arm.com * also send back free registers of either type. This is a very simple 10912153Sandreas.sandberg@arm.com * class, but it should be sufficient for most implementations. Like all 11012150Sgabor.dozsa@arm.com * other classes, it assumes that the indices for the floating point 11112150Sgabor.dozsa@arm.com * registers starts after the integer registers end. Hence the variable 11212150Sgabor.dozsa@arm.com * numPhysicalIntRegs is logically equivalent to the baseFP dependency. 11312150Sgabor.dozsa@arm.com * Note that while this most likely should be called FreeList, the name 11412150Sgabor.dozsa@arm.com * "FreeList" is used in a typedef within the CPU Policy, and therefore no 11512150Sgabor.dozsa@arm.com * class can be named simply "FreeList". 11612150Sgabor.dozsa@arm.com * @todo: Give a better name to the base FP dependency. 11712150Sgabor.dozsa@arm.com */ 11812150Sgabor.dozsa@arm.comclass UnifiedFreeList 11912150Sgabor.dozsa@arm.com{ 12012150Sgabor.dozsa@arm.com private: 12112150Sgabor.dozsa@arm.com 12212150Sgabor.dozsa@arm.com /** The object name, for DPRINTF. We have to declare this 12312150Sgabor.dozsa@arm.com * explicitly because Scoreboard is not a SimObject. */ 12412150Sgabor.dozsa@arm.com const std::string _name; 12512150Sgabor.dozsa@arm.com 12612150Sgabor.dozsa@arm.com /** The list of free integer registers. */ 12712150Sgabor.dozsa@arm.com SimpleFreeList intList; 12812150Sgabor.dozsa@arm.com 12912150Sgabor.dozsa@arm.com /** The list of free floating point registers. */ 13012150Sgabor.dozsa@arm.com SimpleFreeList floatList; 13112150Sgabor.dozsa@arm.com 13212150Sgabor.dozsa@arm.com /** The following two are exclusive interfaces. */ 13312150Sgabor.dozsa@arm.com /** @{ */ 13412150Sgabor.dozsa@arm.com /** The list of free vector registers. */ 13512150Sgabor.dozsa@arm.com SimpleFreeList vecList; 13612150Sgabor.dozsa@arm.com 13712150Sgabor.dozsa@arm.com /** The list of free vector element registers. */ 13812150Sgabor.dozsa@arm.com SimpleFreeList vecElemList; 13912150Sgabor.dozsa@arm.com /** @} */ 14012150Sgabor.dozsa@arm.com 14112150Sgabor.dozsa@arm.com /** The list of free condition-code registers. */ 14212150Sgabor.dozsa@arm.com SimpleFreeList ccList; 14312150Sgabor.dozsa@arm.com 14412150Sgabor.dozsa@arm.com /** 14512150Sgabor.dozsa@arm.com * The register file object is used only to distinguish integer 14612150Sgabor.dozsa@arm.com * from floating-point physical register indices. 14712150Sgabor.dozsa@arm.com */ 14812150Sgabor.dozsa@arm.com PhysRegFile *regFile; 14912150Sgabor.dozsa@arm.com 15013609Sgiacomo.travaglini@arm.com /* 15113609Sgiacomo.travaglini@arm.com * We give UnifiedRenameMap internal access so it can get at the 15213609Sgiacomo.travaglini@arm.com * internal per-class free lists and associate those with its 15313609Sgiacomo.travaglini@arm.com * per-class rename maps. See UnifiedRenameMap::init(). 15413609Sgiacomo.travaglini@arm.com */ 15513609Sgiacomo.travaglini@arm.com friend class UnifiedRenameMap; 15612150Sgabor.dozsa@arm.com 15712150Sgabor.dozsa@arm.com public: 15812150Sgabor.dozsa@arm.com /** Constructs a free list. 15912150Sgabor.dozsa@arm.com * @param _numPhysicalIntRegs Number of physical integer registers. 16012150Sgabor.dozsa@arm.com * @param reservedIntRegs Number of integer registers already 16112150Sgabor.dozsa@arm.com * used by initial mappings. 16212150Sgabor.dozsa@arm.com * @param _numPhysicalFloatRegs Number of physical fp registers. 16312150Sgabor.dozsa@arm.com * @param reservedFloatRegs Number of fp registers already 16412150Sgabor.dozsa@arm.com * used by initial mappings. 16512150Sgabor.dozsa@arm.com */ 16612150Sgabor.dozsa@arm.com UnifiedFreeList(const std::string &_my_name, PhysRegFile *_regFile); 16712150Sgabor.dozsa@arm.com 16812150Sgabor.dozsa@arm.com /** Gives the name of the freelist. */ 16912150Sgabor.dozsa@arm.com std::string name() const { return _name; }; 17012150Sgabor.dozsa@arm.com 17112150Sgabor.dozsa@arm.com /** Returns a pointer to the condition-code free list */ 17212150Sgabor.dozsa@arm.com SimpleFreeList *getCCList() { return &ccList; } 17312150Sgabor.dozsa@arm.com 17412150Sgabor.dozsa@arm.com /** Gets a free integer register. */ 17512150Sgabor.dozsa@arm.com PhysRegIdPtr getIntReg() { return intList.getReg(); } 17612150Sgabor.dozsa@arm.com 17712150Sgabor.dozsa@arm.com /** Gets a free fp register. */ 17812150Sgabor.dozsa@arm.com PhysRegIdPtr getFloatReg() { return floatList.getReg(); } 17912150Sgabor.dozsa@arm.com 18012564Sgabeblack@google.com /** Gets a free vector register. */ 18112150Sgabor.dozsa@arm.com PhysRegIdPtr getVecReg() { return vecList.getReg(); } 18212150Sgabor.dozsa@arm.com 18312150Sgabor.dozsa@arm.com /** Gets a free vector elemenet register. */ 18412150Sgabor.dozsa@arm.com PhysRegIdPtr getVecElem() { return vecElemList.getReg(); } 18512150Sgabor.dozsa@arm.com 18612564Sgabeblack@google.com /** Gets a free cc register. */ 18712150Sgabor.dozsa@arm.com PhysRegIdPtr getCCReg() { return ccList.getReg(); } 18812150Sgabor.dozsa@arm.com 18912564Sgabeblack@google.com /** Adds a register back to the free list. */ 19012150Sgabor.dozsa@arm.com void addReg(PhysRegIdPtr freed_reg); 19112564Sgabeblack@google.com 19212150Sgabor.dozsa@arm.com /** Adds a register back to the free list. */ 19312150Sgabor.dozsa@arm.com template<class InputIt> 19412150Sgabor.dozsa@arm.com void addRegs(InputIt first, InputIt last); 19512150Sgabor.dozsa@arm.com 19612150Sgabor.dozsa@arm.com /** Adds an integer register back to the free list. */ 19712150Sgabor.dozsa@arm.com void addIntReg(PhysRegIdPtr freed_reg) { intList.addReg(freed_reg); } 19812150Sgabor.dozsa@arm.com 19912150Sgabor.dozsa@arm.com /** Adds a fp register back to the free list. */ 20012150Sgabor.dozsa@arm.com void addFloatReg(PhysRegIdPtr freed_reg) { floatList.addReg(freed_reg); } 20112150Sgabor.dozsa@arm.com 20212150Sgabor.dozsa@arm.com /** Adds a vector register back to the free list. */ 20312150Sgabor.dozsa@arm.com void addVecReg(PhysRegIdPtr freed_reg) { vecList.addReg(freed_reg); } 20412150Sgabor.dozsa@arm.com 20512150Sgabor.dozsa@arm.com /** Adds a vector element register back to the free list. */ 20612150Sgabor.dozsa@arm.com void addVecElem(PhysRegIdPtr freed_reg) { 20712150Sgabor.dozsa@arm.com vecElemList.addReg(freed_reg); 20812150Sgabor.dozsa@arm.com } 20912150Sgabor.dozsa@arm.com 21012150Sgabor.dozsa@arm.com /** Adds a cc register back to the free list. */ 21112150Sgabor.dozsa@arm.com void addCCReg(PhysRegIdPtr freed_reg) { ccList.addReg(freed_reg); } 21212150Sgabor.dozsa@arm.com 21312150Sgabor.dozsa@arm.com /** Checks if there are any free integer registers. */ 21412150Sgabor.dozsa@arm.com bool hasFreeIntRegs() const { return intList.hasFreeRegs(); } 21512150Sgabor.dozsa@arm.com 21612150Sgabor.dozsa@arm.com /** Checks if there are any free fp registers. */ 21712150Sgabor.dozsa@arm.com bool hasFreeFloatRegs() const { return floatList.hasFreeRegs(); } 21812150Sgabor.dozsa@arm.com 21912150Sgabor.dozsa@arm.com /** Checks if there are any free vector registers. */ 22012150Sgabor.dozsa@arm.com bool hasFreeVecRegs() const { return vecList.hasFreeRegs(); } 22112150Sgabor.dozsa@arm.com 22212150Sgabor.dozsa@arm.com /** Checks if there are any free vector registers. */ 22312150Sgabor.dozsa@arm.com bool hasFreeVecElems() const { return vecElemList.hasFreeRegs(); } 22412150Sgabor.dozsa@arm.com 22512150Sgabor.dozsa@arm.com /** Checks if there are any free cc registers. */ 22612150Sgabor.dozsa@arm.com bool hasFreeCCRegs() const { return ccList.hasFreeRegs(); } 22712150Sgabor.dozsa@arm.com 22812150Sgabor.dozsa@arm.com /** Returns the number of free integer registers. */ 22912150Sgabor.dozsa@arm.com unsigned numFreeIntRegs() const { return intList.numFreeRegs(); } 23012150Sgabor.dozsa@arm.com 23112150Sgabor.dozsa@arm.com /** Returns the number of free fp registers. */ 23212150Sgabor.dozsa@arm.com unsigned numFreeFloatRegs() const { return floatList.numFreeRegs(); } 23312150Sgabor.dozsa@arm.com 23412150Sgabor.dozsa@arm.com /** Returns the number of free vector registers. */ 23512150Sgabor.dozsa@arm.com unsigned numFreeVecRegs() const { return vecList.numFreeRegs(); } 23612150Sgabor.dozsa@arm.com 23712150Sgabor.dozsa@arm.com /** Returns the number of free cc registers. */ 23812150Sgabor.dozsa@arm.com unsigned numFreeCCRegs() const { return ccList.numFreeRegs(); } 23912150Sgabor.dozsa@arm.com}; 24012150Sgabor.dozsa@arm.com 24112150Sgabor.dozsa@arm.comtemplate<class InputIt> 24212150Sgabor.dozsa@arm.cominline void 24312150Sgabor.dozsa@arm.comUnifiedFreeList::addRegs(InputIt first, InputIt last) 244{ 245 // Are there any registers to add? 246 if (first == last) 247 return; 248 249 panic_if((first != last) && 250 first->classValue() != (last-1)->classValue(), 251 "Attempt to add mixed type regs: %s and %s", 252 first->className(), 253 (last-1)->className()); 254 switch (first->classValue()) { 255 case IntRegClass: 256 intList.addRegs(first, last); 257 break; 258 case FloatRegClass: 259 floatList.addRegs(first, last); 260 break; 261 case VecRegClass: 262 vecList.addRegs(first, last); 263 break; 264 case VecElemClass: 265 vecElemList.addRegs(first, last); 266 break; 267 case CCRegClass: 268 ccList.addRegs(first, last); 269 break; 270 default: 271 panic("Unexpected RegClass (%s)", 272 first->className()); 273 } 274 275} 276 277inline void 278UnifiedFreeList::addReg(PhysRegIdPtr freed_reg) 279{ 280 DPRINTF(FreeList,"Freeing register %i (%s).\n", freed_reg->index(), 281 freed_reg->className()); 282 //Might want to add in a check for whether or not this register is 283 //already in there. A bit vector or something similar would be useful. 284 switch (freed_reg->classValue()) { 285 case IntRegClass: 286 intList.addReg(freed_reg); 287 break; 288 case FloatRegClass: 289 floatList.addReg(freed_reg); 290 break; 291 case VecRegClass: 292 vecList.addReg(freed_reg); 293 break; 294 case VecElemClass: 295 vecElemList.addReg(freed_reg); 296 break; 297 case CCRegClass: 298 ccList.addReg(freed_reg); 299 break; 300 default: 301 panic("Unexpected RegClass (%s)", 302 freed_reg->className()); 303 } 304 305 // These assert conditions ensure that the number of free 306 // registers are not more than the # of total Physical Registers. 307 // If this were false, it would mean that registers 308 // have been freed twice, overflowing the free register 309 // pool and potentially crashing SMT workloads. 310 // ---- 311 // Comment out for now so as to not potentially break 312 // CMP and single-threaded workloads 313 // ---- 314 // assert(freeIntRegs.size() <= numPhysicalIntRegs); 315 // assert(freeFloatRegs.size() <= numPhysicalFloatRegs); 316} 317 318 319#endif // __CPU_O3_FREE_LIST_HH__ 320