free_list.hh revision 12334
1/* 2 * Copyright (c) 2016 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 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