free_list.hh revision 9919
1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer; 10 * redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution; 13 * neither the name of the copyright holders nor the names of its 14 * contributors may be used to endorse or promote products derived from 15 * this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * Authors: Kevin Lim 30 */ 31 32#ifndef __CPU_O3_FREE_LIST_HH__ 33#define __CPU_O3_FREE_LIST_HH__ 34 35#include <iostream> 36#include <queue> 37 38#include "base/misc.hh" 39#include "base/trace.hh" 40#include "cpu/o3/comm.hh" 41#include "cpu/o3/regfile.hh" 42#include "debug/FreeList.hh" 43 44/** 45 * Free list for a single class of registers (e.g., integer 46 * or floating point). Because the register class is implicitly 47 * determined by the rename map instance being accessed, all 48 * architectural register index parameters and values in this class 49 * are relative (e.g., %fp2 is just index 2). 50 */ 51class SimpleFreeList 52{ 53 private: 54 55 /** The actual free list */ 56 std::queue<PhysRegIndex> freeRegs; 57 58 public: 59 60 SimpleFreeList() {}; 61 62 /** Add a physical register to the free list */ 63 void addReg(PhysRegIndex reg) { freeRegs.push(reg); } 64 65 /** Get the next available register from the free list */ 66 PhysRegIndex getReg() 67 { 68 assert(!freeRegs.empty()); 69 PhysRegIndex free_reg = freeRegs.front(); 70 freeRegs.pop(); 71 return free_reg; 72 } 73 74 /** Return the number of free registers on the list. */ 75 unsigned numFreeRegs() const { return freeRegs.size(); } 76 77 /** True iff there are free registers on the list. */ 78 bool hasFreeRegs() const { return !freeRegs.empty(); } 79}; 80 81 82/** 83 * FreeList class that simply holds the list of free integer and floating 84 * point registers. Can request for a free register of either type, and 85 * also send back free registers of either type. This is a very simple 86 * class, but it should be sufficient for most implementations. Like all 87 * other classes, it assumes that the indices for the floating point 88 * registers starts after the integer registers end. Hence the variable 89 * numPhysicalIntRegs is logically equivalent to the baseFP dependency. 90 * Note that while this most likely should be called FreeList, the name 91 * "FreeList" is used in a typedef within the CPU Policy, and therefore no 92 * class can be named simply "FreeList". 93 * @todo: Give a better name to the base FP dependency. 94 */ 95class UnifiedFreeList 96{ 97 private: 98 99 /** The object name, for DPRINTF. We have to declare this 100 * explicitly because Scoreboard is not a SimObject. */ 101 const std::string _name; 102 103 /** The list of free integer registers. */ 104 SimpleFreeList intList; 105 106 /** The list of free floating point registers. */ 107 SimpleFreeList floatList; 108 109 /** 110 * The register file object is used only to distinguish integer 111 * from floating-point physical register indices. 112 */ 113 PhysRegFile *regFile; 114 115 /* 116 * We give UnifiedRenameMap internal access so it can get at the 117 * internal per-class free lists and associate those with its 118 * per-class rename maps. See UnifiedRenameMap::init(). 119 */ 120 friend class UnifiedRenameMap; 121 122 public: 123 /** Constructs a free list. 124 * @param _numPhysicalIntRegs Number of physical integer registers. 125 * @param reservedIntRegs Number of integer registers already 126 * used by initial mappings. 127 * @param _numPhysicalFloatRegs Number of physical fp registers. 128 * @param reservedFloatRegs Number of fp registers already 129 * used by initial mappings. 130 */ 131 UnifiedFreeList(const std::string &_my_name, PhysRegFile *_regFile); 132 133 /** Gives the name of the freelist. */ 134 std::string name() const { return _name; }; 135 136 /** Gets a free integer register. */ 137 PhysRegIndex getIntReg() { return intList.getReg(); } 138 139 /** Gets a free fp register. */ 140 PhysRegIndex getFloatReg() { return floatList.getReg(); } 141 142 /** Adds a register back to the free list. */ 143 void addReg(PhysRegIndex freed_reg); 144 145 /** Adds an integer register back to the free list. */ 146 void addIntReg(PhysRegIndex freed_reg) { intList.addReg(freed_reg); } 147 148 /** Adds a fp register back to the free list. */ 149 void addFloatReg(PhysRegIndex freed_reg) { floatList.addReg(freed_reg); } 150 151 /** Checks if there are any free integer registers. */ 152 bool hasFreeIntRegs() const { return intList.hasFreeRegs(); } 153 154 /** Checks if there are any free fp registers. */ 155 bool hasFreeFloatRegs() const { return floatList.hasFreeRegs(); } 156 157 /** Returns the number of free integer registers. */ 158 unsigned numFreeIntRegs() const { return intList.numFreeRegs(); } 159 160 /** Returns the number of free fp registers. */ 161 unsigned numFreeFloatRegs() const { return floatList.numFreeRegs(); } 162}; 163 164inline void 165UnifiedFreeList::addReg(PhysRegIndex freed_reg) 166{ 167 DPRINTF(FreeList,"Freeing register %i.\n", freed_reg); 168 //Might want to add in a check for whether or not this register is 169 //already in there. A bit vector or something similar would be useful. 170 if (regFile->isIntPhysReg(freed_reg)) { 171 intList.addReg(freed_reg); 172 } else { 173 assert(regFile->isFloatPhysReg(freed_reg)); 174 floatList.addReg(freed_reg); 175 } 176 177 // These assert conditions ensure that the number of free 178 // registers are not more than the # of total Physical Registers. 179 // If this were false, it would mean that registers 180 // have been freed twice, overflowing the free register 181 // pool and potentially crashing SMT workloads. 182 // ---- 183 // Comment out for now so as to not potentially break 184 // CMP and single-threaded workloads 185 // ---- 186 // assert(freeIntRegs.size() <= numPhysicalIntRegs); 187 // assert(freeFloatRegs.size() <= numPhysicalFloatRegs); 188} 189 190 191#endif // __CPU_O3_FREE_LIST_HH__ 192