free_list.hh revision 12109
18914Sandreas.hansson@arm.com/* 28914Sandreas.hansson@arm.com * Copyright (c) 2016 ARM Limited 38914Sandreas.hansson@arm.com * All rights reserved 48914Sandreas.hansson@arm.com * 58914Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 68914Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 78914Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 88914Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 98914Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 108914Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 118914Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 128914Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 138914Sandreas.hansson@arm.com * 148914Sandreas.hansson@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 158914Sandreas.hansson@arm.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 168914Sandreas.hansson@arm.com * All rights reserved. 178914Sandreas.hansson@arm.com * 188914Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 198914Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 208914Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 218914Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 228914Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 238914Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 248914Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 258914Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 268914Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 278914Sandreas.hansson@arm.com * this software without specific prior written permission. 288914Sandreas.hansson@arm.com * 298914Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 308914Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 318914Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 328914Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 338914Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 348914Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 358914Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 368914Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 378914Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 388914Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 398914Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 408914Sandreas.hansson@arm.com * 418914Sandreas.hansson@arm.com * Authors: Kevin Lim 428914Sandreas.hansson@arm.com */ 438914Sandreas.hansson@arm.com 448914Sandreas.hansson@arm.com#ifndef __CPU_O3_FREE_LIST_HH__ 458914Sandreas.hansson@arm.com#define __CPU_O3_FREE_LIST_HH__ 468914Sandreas.hansson@arm.com 478914Sandreas.hansson@arm.com#include <iostream> 488914Sandreas.hansson@arm.com#include <queue> 498914Sandreas.hansson@arm.com#include <vector> 508914Sandreas.hansson@arm.com 518914Sandreas.hansson@arm.com#include "base/misc.hh" 528914Sandreas.hansson@arm.com#include "base/trace.hh" 538914Sandreas.hansson@arm.com#include "cpu/o3/comm.hh" 548914Sandreas.hansson@arm.com#include "cpu/o3/regfile.hh" 558914Sandreas.hansson@arm.com#include "debug/FreeList.hh" 568914Sandreas.hansson@arm.com 578914Sandreas.hansson@arm.com/** 588914Sandreas.hansson@arm.com * Free list for a single class of registers (e.g., integer 598922Swilliam.wang@arm.com * or floating point). Because the register class is implicitly 608914Sandreas.hansson@arm.com * determined by the rename map instance being accessed, all 618914Sandreas.hansson@arm.com * architectural register index parameters and values in this class 628914Sandreas.hansson@arm.com * are relative (e.g., %fp2 is just index 2). 638914Sandreas.hansson@arm.com */ 648914Sandreas.hansson@arm.comclass SimpleFreeList 658914Sandreas.hansson@arm.com{ 668914Sandreas.hansson@arm.com private: 678914Sandreas.hansson@arm.com 688914Sandreas.hansson@arm.com /** The actual free list */ 698914Sandreas.hansson@arm.com std::queue<PhysRegIdPtr> freeRegs; 708914Sandreas.hansson@arm.com 718922Swilliam.wang@arm.com public: 728922Swilliam.wang@arm.com 738922Swilliam.wang@arm.com SimpleFreeList() {}; 748922Swilliam.wang@arm.com 758922Swilliam.wang@arm.com /** Add a physical register to the free list */ 768922Swilliam.wang@arm.com void addReg(PhysRegIdPtr reg) { freeRegs.push(reg); } 778922Swilliam.wang@arm.com 788922Swilliam.wang@arm.com /** Add physical registers to the free list */ 798922Swilliam.wang@arm.com template<class InputIt> 808922Swilliam.wang@arm.com void 818922Swilliam.wang@arm.com addRegs(InputIt first, InputIt last) { 828922Swilliam.wang@arm.com std::for_each(first, last, 838922Swilliam.wang@arm.com [this](const typename InputIt::value_type& reg) { 848922Swilliam.wang@arm.com this->freeRegs.push(®); 858922Swilliam.wang@arm.com }); 868922Swilliam.wang@arm.com } 878922Swilliam.wang@arm.com 888922Swilliam.wang@arm.com /** Get the next available register from the free list */ 898922Swilliam.wang@arm.com PhysRegIdPtr getReg() 908922Swilliam.wang@arm.com { 918922Swilliam.wang@arm.com assert(!freeRegs.empty()); 928922Swilliam.wang@arm.com PhysRegIdPtr free_reg = freeRegs.front(); 938922Swilliam.wang@arm.com freeRegs.pop(); 948922Swilliam.wang@arm.com return free_reg; 958922Swilliam.wang@arm.com } 968922Swilliam.wang@arm.com 978922Swilliam.wang@arm.com /** Return the number of free registers on the list. */ 988922Swilliam.wang@arm.com unsigned numFreeRegs() const { return freeRegs.size(); } 998922Swilliam.wang@arm.com 1008922Swilliam.wang@arm.com /** True iff there are free registers on the list. */ 1018922Swilliam.wang@arm.com bool hasFreeRegs() const { return !freeRegs.empty(); } 1028922Swilliam.wang@arm.com}; 1038922Swilliam.wang@arm.com 1048922Swilliam.wang@arm.com 1058922Swilliam.wang@arm.com/** 1068922Swilliam.wang@arm.com * FreeList class that simply holds the list of free integer and floating 1078922Swilliam.wang@arm.com * point registers. Can request for a free register of either type, and 1088922Swilliam.wang@arm.com * also send back free registers of either type. This is a very simple 1098922Swilliam.wang@arm.com * class, but it should be sufficient for most implementations. Like all 1108922Swilliam.wang@arm.com * other classes, it assumes that the indices for the floating point 1118914Sandreas.hansson@arm.com * registers starts after the integer registers end. Hence the variable 1128914Sandreas.hansson@arm.com * numPhysicalIntRegs is logically equivalent to the baseFP dependency. 1138914Sandreas.hansson@arm.com * Note that while this most likely should be called FreeList, the name 1148914Sandreas.hansson@arm.com * "FreeList" is used in a typedef within the CPU Policy, and therefore no 1158914Sandreas.hansson@arm.com * class can be named simply "FreeList". 1168914Sandreas.hansson@arm.com * @todo: Give a better name to the base FP dependency. 1178914Sandreas.hansson@arm.com */ 1188914Sandreas.hansson@arm.comclass UnifiedFreeList 1198914Sandreas.hansson@arm.com{ 1208914Sandreas.hansson@arm.com private: 1218922Swilliam.wang@arm.com 1228922Swilliam.wang@arm.com /** The object name, for DPRINTF. We have to declare this 1238922Swilliam.wang@arm.com * explicitly because Scoreboard is not a SimObject. */ 1248914Sandreas.hansson@arm.com const std::string _name; 1258914Sandreas.hansson@arm.com 1268922Swilliam.wang@arm.com /** The list of free integer registers. */ 1278914Sandreas.hansson@arm.com SimpleFreeList intList; 1288914Sandreas.hansson@arm.com 1298914Sandreas.hansson@arm.com /** The list of free floating point registers. */ 1308914Sandreas.hansson@arm.com SimpleFreeList floatList; 1318914Sandreas.hansson@arm.com 1328914Sandreas.hansson@arm.com /** The following two are exclusive interfaces. */ 1338914Sandreas.hansson@arm.com /** @{ */ 1348914Sandreas.hansson@arm.com /** The list of free vector registers. */ 1358914Sandreas.hansson@arm.com SimpleFreeList vecList; 1368914Sandreas.hansson@arm.com 1378914Sandreas.hansson@arm.com /** The list of free vector element registers. */ 1388914Sandreas.hansson@arm.com SimpleFreeList vecElemList; 1398914Sandreas.hansson@arm.com /** @} */ 1408914Sandreas.hansson@arm.com 1418914Sandreas.hansson@arm.com /** The list of free condition-code registers. */ 142 SimpleFreeList ccList; 143 144 /** 145 * The register file object is used only to distinguish integer 146 * from floating-point physical register indices. 147 */ 148 PhysRegFile *regFile; 149 150 /* 151 * We give UnifiedRenameMap internal access so it can get at the 152 * internal per-class free lists and associate those with its 153 * per-class rename maps. See UnifiedRenameMap::init(). 154 */ 155 friend class UnifiedRenameMap; 156 157 public: 158 /** Constructs a free list. 159 * @param _numPhysicalIntRegs Number of physical integer registers. 160 * @param reservedIntRegs Number of integer registers already 161 * used by initial mappings. 162 * @param _numPhysicalFloatRegs Number of physical fp registers. 163 * @param reservedFloatRegs Number of fp registers already 164 * used by initial mappings. 165 */ 166 UnifiedFreeList(const std::string &_my_name, PhysRegFile *_regFile); 167 168 /** Gives the name of the freelist. */ 169 std::string name() const { return _name; }; 170 171 /** Returns a pointer to the condition-code free list */ 172 SimpleFreeList *getCCList() { return &ccList; } 173 174 /** Gets a free integer register. */ 175 PhysRegIdPtr getIntReg() { return intList.getReg(); } 176 177 /** Gets a free fp register. */ 178 PhysRegIdPtr getFloatReg() { return floatList.getReg(); } 179 180 /** Gets a free vector register. */ 181 PhysRegIdPtr getVecReg() { return vecList.getReg(); } 182 183 /** Gets a free vector elemenet register. */ 184 PhysRegIdPtr getVecElem() { return vecElemList.getReg(); } 185 186 /** Gets a free cc register. */ 187 PhysRegIdPtr getCCReg() { return ccList.getReg(); } 188 189 /** Adds a register back to the free list. */ 190 void addReg(PhysRegIdPtr freed_reg); 191 192 /** Adds a register back to the free list. */ 193 template<class InputIt> 194 void addRegs(InputIt first, InputIt last); 195 196 /** Adds an integer register back to the free list. */ 197 void addIntReg(PhysRegIdPtr freed_reg) { intList.addReg(freed_reg); } 198 199 /** Adds a fp register back to the free list. */ 200 void addFloatReg(PhysRegIdPtr freed_reg) { floatList.addReg(freed_reg); } 201 202 /** Adds a vector register back to the free list. */ 203 void addVecReg(PhysRegIdPtr freed_reg) { vecList.addReg(freed_reg); } 204 205 /** Adds a vector element register back to the free list. */ 206 void addVecElem(PhysRegIdPtr freed_reg) { 207 vecElemList.addReg(freed_reg); 208 } 209 210 /** Adds a cc register back to the free list. */ 211 void addCCReg(PhysRegIdPtr freed_reg) { ccList.addReg(freed_reg); } 212 213 /** Checks if there are any free integer registers. */ 214 bool hasFreeIntRegs() const { return intList.hasFreeRegs(); } 215 216 /** Checks if there are any free fp registers. */ 217 bool hasFreeFloatRegs() const { return floatList.hasFreeRegs(); } 218 219 /** Checks if there are any free vector registers. */ 220 bool hasFreeVecRegs() const { return vecList.hasFreeRegs(); } 221 222 /** Checks if there are any free vector registers. */ 223 bool hasFreeVecElems() const { return vecElemList.hasFreeRegs(); } 224 225 /** Checks if there are any free cc registers. */ 226 bool hasFreeCCRegs() const { return ccList.hasFreeRegs(); } 227 228 /** Returns the number of free integer registers. */ 229 unsigned numFreeIntRegs() const { return intList.numFreeRegs(); } 230 231 /** Returns the number of free fp registers. */ 232 unsigned numFreeFloatRegs() const { return floatList.numFreeRegs(); } 233 234 /** Returns the number of free vector registers. */ 235 unsigned numFreeVecRegs() const { return vecList.numFreeRegs(); } 236 237 /** Returns the number of free cc registers. */ 238 unsigned numFreeCCRegs() const { return ccList.numFreeRegs(); } 239}; 240 241template<class InputIt> 242inline void 243UnifiedFreeList::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