free_list.hh revision 13610:5d5404ac6288
1/* 2 * Copyright (c) 2016-2017 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Copyright (c) 2004-2005 The Regents of The University of Michigan 15 * Copyright (c) 2013 Advanced Micro Devices, Inc. 16 * All rights reserved. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions are 20 * met: redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer; 22 * redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution; 25 * neither the name of the copyright holders nor the names of its 26 * contributors may be used to endorse or promote products derived from 27 * this software without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Authors: Kevin Lim 42 */ 43 44#ifndef __CPU_O3_FREE_LIST_HH__ 45#define __CPU_O3_FREE_LIST_HH__ 46 47#include <iostream> 48#include <queue> 49#include <vector> 50 51#include "base/logging.hh" 52#include "base/trace.hh" 53#include "cpu/o3/comm.hh" 54#include "cpu/o3/regfile.hh" 55#include "debug/FreeList.hh" 56 57/** 58 * Free list for a single class of registers (e.g., integer 59 * or floating point). Because the register class is implicitly 60 * determined by the rename map instance being accessed, all 61 * architectural register index parameters and values in this class 62 * are relative (e.g., %fp2 is just index 2). 63 */ 64class SimpleFreeList 65{ 66 private: 67 68 /** The actual free list */ 69 std::queue<PhysRegIdPtr> freeRegs; 70 71 public: 72 73 SimpleFreeList() {}; 74 75 /** Add a physical register to the free list */ 76 void addReg(PhysRegIdPtr reg) { freeRegs.push(reg); } 77 78 /** Add physical registers to the free list */ 79 template<class InputIt> 80 void 81 addRegs(InputIt first, InputIt last) { 82 std::for_each(first, last, 83 [this](const typename InputIt::value_type& reg) { 84 this->freeRegs.push(®); 85 }); 86 } 87 88 /** Get the next available register from the free list */ 89 PhysRegIdPtr getReg() 90 { 91 assert(!freeRegs.empty()); 92 PhysRegIdPtr free_reg = freeRegs.front(); 93 freeRegs.pop(); 94 return free_reg; 95 } 96 97 /** Return the number of free registers on the list. */ 98 unsigned numFreeRegs() const { return freeRegs.size(); } 99 100 /** True iff there are free registers on the list. */ 101 bool hasFreeRegs() const { return !freeRegs.empty(); } 102}; 103 104 105/** 106 * FreeList class that simply holds the list of free integer and floating 107 * point registers. Can request for a free register of either type, and 108 * also send back free registers of either type. This is a very simple 109 * class, but it should be sufficient for most implementations. Like all 110 * other classes, it assumes that the indices for the floating point 111 * registers starts after the integer registers end. Hence the variable 112 * numPhysicalIntRegs is logically equivalent to the baseFP dependency. 113 * Note that while this most likely should be called FreeList, the name 114 * "FreeList" is used in a typedef within the CPU Policy, and therefore no 115 * class can be named simply "FreeList". 116 * @todo: Give a better name to the base FP dependency. 117 */ 118class UnifiedFreeList 119{ 120 private: 121 122 /** The object name, for DPRINTF. We have to declare this 123 * explicitly because Scoreboard is not a SimObject. */ 124 const std::string _name; 125 126 /** The list of free integer registers. */ 127 SimpleFreeList intList; 128 129 /** The list of free floating point registers. */ 130 SimpleFreeList floatList; 131 132 /** The following two are exclusive interfaces. */ 133 /** @{ */ 134 /** The list of free vector registers. */ 135 SimpleFreeList vecList; 136 137 /** The list of free vector element registers. */ 138 SimpleFreeList vecElemList; 139 /** @} */ 140 141 /** The list of free predicate registers. */ 142 SimpleFreeList predList; 143 144 /** The list of free condition-code registers. */ 145 SimpleFreeList ccList; 146 147 /** 148 * The register file object is used only to distinguish integer 149 * from floating-point physical register indices. 150 */ 151 PhysRegFile *regFile; 152 153 /* 154 * We give UnifiedRenameMap internal access so it can get at the 155 * internal per-class free lists and associate those with its 156 * per-class rename maps. See UnifiedRenameMap::init(). 157 */ 158 friend class UnifiedRenameMap; 159 160 public: 161 /** Constructs a free list. 162 * @param _numPhysicalIntRegs Number of physical integer registers. 163 * @param reservedIntRegs Number of integer registers already 164 * used by initial mappings. 165 * @param _numPhysicalFloatRegs Number of physical fp registers. 166 * @param reservedFloatRegs Number of fp registers already 167 * used by initial mappings. 168 */ 169 UnifiedFreeList(const std::string &_my_name, PhysRegFile *_regFile); 170 171 /** Gives the name of the freelist. */ 172 std::string name() const { return _name; }; 173 174 /** Returns a pointer to the condition-code free list */ 175 SimpleFreeList *getCCList() { return &ccList; } 176 177 /** Gets a free integer register. */ 178 PhysRegIdPtr getIntReg() { return intList.getReg(); } 179 180 /** Gets a free fp register. */ 181 PhysRegIdPtr getFloatReg() { return floatList.getReg(); } 182 183 /** Gets a free vector register. */ 184 PhysRegIdPtr getVecReg() { return vecList.getReg(); } 185 186 /** Gets a free vector elemenet register. */ 187 PhysRegIdPtr getVecElem() { return vecElemList.getReg(); } 188 189 /** Gets a free predicate register. */ 190 PhysRegIdPtr getVecPredReg() { return predList.getReg(); } 191 192 /** Gets a free cc register. */ 193 PhysRegIdPtr getCCReg() { return ccList.getReg(); } 194 195 /** Adds a register back to the free list. */ 196 void addReg(PhysRegIdPtr freed_reg); 197 198 /** Adds a register back to the free list. */ 199 template<class InputIt> 200 void addRegs(InputIt first, InputIt last); 201 202 /** Adds an integer register back to the free list. */ 203 void addIntReg(PhysRegIdPtr freed_reg) { intList.addReg(freed_reg); } 204 205 /** Adds a fp register back to the free list. */ 206 void addFloatReg(PhysRegIdPtr freed_reg) { floatList.addReg(freed_reg); } 207 208 /** Adds a vector register back to the free list. */ 209 void addVecReg(PhysRegIdPtr freed_reg) { vecList.addReg(freed_reg); } 210 211 /** Adds a vector element register back to the free list. */ 212 void addVecElem(PhysRegIdPtr freed_reg) { 213 vecElemList.addReg(freed_reg); 214 } 215 216 /** Adds a predicate register back to the free list. */ 217 void addVecPredReg(PhysRegIdPtr freed_reg) { predList.addReg(freed_reg); } 218 219 /** Adds a cc register back to the free list. */ 220 void addCCReg(PhysRegIdPtr freed_reg) { ccList.addReg(freed_reg); } 221 222 /** Checks if there are any free integer registers. */ 223 bool hasFreeIntRegs() const { return intList.hasFreeRegs(); } 224 225 /** Checks if there are any free fp registers. */ 226 bool hasFreeFloatRegs() const { return floatList.hasFreeRegs(); } 227 228 /** Checks if there are any free vector registers. */ 229 bool hasFreeVecRegs() const { return vecList.hasFreeRegs(); } 230 231 /** Checks if there are any free vector registers. */ 232 bool hasFreeVecElems() const { return vecElemList.hasFreeRegs(); } 233 234 /** Checks if there are any free predicate registers. */ 235 bool hasFreeVecPredRegs() const { return predList.hasFreeRegs(); } 236 237 /** Checks if there are any free cc registers. */ 238 bool hasFreeCCRegs() const { return ccList.hasFreeRegs(); } 239 240 /** Returns the number of free integer registers. */ 241 unsigned numFreeIntRegs() const { return intList.numFreeRegs(); } 242 243 /** Returns the number of free fp registers. */ 244 unsigned numFreeFloatRegs() const { return floatList.numFreeRegs(); } 245 246 /** Returns the number of free vector registers. */ 247 unsigned numFreeVecRegs() const { return vecList.numFreeRegs(); } 248 249 /** Returns the number of free vector registers. */ 250 unsigned numFreeVecElems() const { return vecElemList.numFreeRegs(); } 251 252 /** Returns the number of free predicate registers. */ 253 unsigned numFreeVecPredRegs() const { return predList.numFreeRegs(); } 254 255 /** Returns the number of free cc registers. */ 256 unsigned numFreeCCRegs() const { return ccList.numFreeRegs(); } 257}; 258 259template<class InputIt> 260inline void 261UnifiedFreeList::addRegs(InputIt first, InputIt last) 262{ 263 // Are there any registers to add? 264 if (first == last) 265 return; 266 267 panic_if((first != last) && 268 first->classValue() != (last-1)->classValue(), 269 "Attempt to add mixed type regs: %s and %s", 270 first->className(), 271 (last-1)->className()); 272 switch (first->classValue()) { 273 case IntRegClass: 274 intList.addRegs(first, last); 275 break; 276 case FloatRegClass: 277 floatList.addRegs(first, last); 278 break; 279 case VecRegClass: 280 vecList.addRegs(first, last); 281 break; 282 case VecElemClass: 283 vecElemList.addRegs(first, last); 284 break; 285 case VecPredRegClass: 286 predList.addRegs(first, last); 287 break; 288 case CCRegClass: 289 ccList.addRegs(first, last); 290 break; 291 default: 292 panic("Unexpected RegClass (%s)", 293 first->className()); 294 } 295 296} 297 298inline void 299UnifiedFreeList::addReg(PhysRegIdPtr freed_reg) 300{ 301 DPRINTF(FreeList,"Freeing register %i (%s).\n", freed_reg->index(), 302 freed_reg->className()); 303 //Might want to add in a check for whether or not this register is 304 //already in there. A bit vector or something similar would be useful. 305 switch (freed_reg->classValue()) { 306 case IntRegClass: 307 intList.addReg(freed_reg); 308 break; 309 case FloatRegClass: 310 floatList.addReg(freed_reg); 311 break; 312 case VecRegClass: 313 vecList.addReg(freed_reg); 314 break; 315 case VecElemClass: 316 vecElemList.addReg(freed_reg); 317 break; 318 case VecPredRegClass: 319 predList.addReg(freed_reg); 320 break; 321 case CCRegClass: 322 ccList.addReg(freed_reg); 323 break; 324 default: 325 panic("Unexpected RegClass (%s)", 326 freed_reg->className()); 327 } 328 329 // These assert conditions ensure that the number of free 330 // registers are not more than the # of total Physical Registers. 331 // If this were false, it would mean that registers 332 // have been freed twice, overflowing the free register 333 // pool and potentially crashing SMT workloads. 334 // ---- 335 // Comment out for now so as to not potentially break 336 // CMP and single-threaded workloads 337 // ---- 338 // assert(freeIntRegs.size() <= numPhysicalIntRegs); 339 // assert(freeFloatRegs.size() <= numPhysicalFloatRegs); 340} 341 342 343#endif // __CPU_O3_FREE_LIST_HH__ 344