free_list.hh revision 9919
11689SN/A/* 21689SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 39919Ssteve.reinhardt@amd.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 41689SN/A * All rights reserved. 51689SN/A * 61689SN/A * Redistribution and use in source and binary forms, with or without 71689SN/A * modification, are permitted provided that the following conditions are 81689SN/A * met: redistributions of source code must retain the above copyright 91689SN/A * notice, this list of conditions and the following disclaimer; 101689SN/A * redistributions in binary form must reproduce the above copyright 111689SN/A * notice, this list of conditions and the following disclaimer in the 121689SN/A * documentation and/or other materials provided with the distribution; 131689SN/A * neither the name of the copyright holders nor the names of its 141689SN/A * contributors may be used to endorse or promote products derived from 151689SN/A * this software without specific prior written permission. 161689SN/A * 171689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 181689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 191689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 201689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 211689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 221689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 231689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 241689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 251689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 261689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 271689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665Ssaidi@eecs.umich.edu * 292665Ssaidi@eecs.umich.edu * Authors: Kevin Lim 301689SN/A */ 311689SN/A 322292SN/A#ifndef __CPU_O3_FREE_LIST_HH__ 332292SN/A#define __CPU_O3_FREE_LIST_HH__ 341060SN/A 351060SN/A#include <iostream> 361060SN/A#include <queue> 371060SN/A 382669Sktlim@umich.edu#include "base/misc.hh" 391684SN/A#include "base/trace.hh" 401717SN/A#include "cpu/o3/comm.hh" 419919Ssteve.reinhardt@amd.com#include "cpu/o3/regfile.hh" 428232Snate@binkert.org#include "debug/FreeList.hh" 431060SN/A 441060SN/A/** 459919Ssteve.reinhardt@amd.com * Free list for a single class of registers (e.g., integer 469919Ssteve.reinhardt@amd.com * or floating point). Because the register class is implicitly 479919Ssteve.reinhardt@amd.com * determined by the rename map instance being accessed, all 489919Ssteve.reinhardt@amd.com * architectural register index parameters and values in this class 499919Ssteve.reinhardt@amd.com * are relative (e.g., %fp2 is just index 2). 509919Ssteve.reinhardt@amd.com */ 519919Ssteve.reinhardt@amd.comclass SimpleFreeList 529919Ssteve.reinhardt@amd.com{ 539919Ssteve.reinhardt@amd.com private: 549919Ssteve.reinhardt@amd.com 559919Ssteve.reinhardt@amd.com /** The actual free list */ 569919Ssteve.reinhardt@amd.com std::queue<PhysRegIndex> freeRegs; 579919Ssteve.reinhardt@amd.com 589919Ssteve.reinhardt@amd.com public: 599919Ssteve.reinhardt@amd.com 609919Ssteve.reinhardt@amd.com SimpleFreeList() {}; 619919Ssteve.reinhardt@amd.com 629919Ssteve.reinhardt@amd.com /** Add a physical register to the free list */ 639919Ssteve.reinhardt@amd.com void addReg(PhysRegIndex reg) { freeRegs.push(reg); } 649919Ssteve.reinhardt@amd.com 659919Ssteve.reinhardt@amd.com /** Get the next available register from the free list */ 669919Ssteve.reinhardt@amd.com PhysRegIndex getReg() 679919Ssteve.reinhardt@amd.com { 689919Ssteve.reinhardt@amd.com assert(!freeRegs.empty()); 699919Ssteve.reinhardt@amd.com PhysRegIndex free_reg = freeRegs.front(); 709919Ssteve.reinhardt@amd.com freeRegs.pop(); 719919Ssteve.reinhardt@amd.com return free_reg; 729919Ssteve.reinhardt@amd.com } 739919Ssteve.reinhardt@amd.com 749919Ssteve.reinhardt@amd.com /** Return the number of free registers on the list. */ 759919Ssteve.reinhardt@amd.com unsigned numFreeRegs() const { return freeRegs.size(); } 769919Ssteve.reinhardt@amd.com 779919Ssteve.reinhardt@amd.com /** True iff there are free registers on the list. */ 789919Ssteve.reinhardt@amd.com bool hasFreeRegs() const { return !freeRegs.empty(); } 799919Ssteve.reinhardt@amd.com}; 809919Ssteve.reinhardt@amd.com 819919Ssteve.reinhardt@amd.com 829919Ssteve.reinhardt@amd.com/** 831060SN/A * FreeList class that simply holds the list of free integer and floating 841060SN/A * point registers. Can request for a free register of either type, and 851060SN/A * also send back free registers of either type. This is a very simple 861060SN/A * class, but it should be sufficient for most implementations. Like all 871060SN/A * other classes, it assumes that the indices for the floating point 881060SN/A * registers starts after the integer registers end. Hence the variable 891060SN/A * numPhysicalIntRegs is logically equivalent to the baseFP dependency. 902292SN/A * Note that while this most likely should be called FreeList, the name 912292SN/A * "FreeList" is used in a typedef within the CPU Policy, and therefore no 922292SN/A * class can be named simply "FreeList". 931060SN/A * @todo: Give a better name to the base FP dependency. 941060SN/A */ 959919Ssteve.reinhardt@amd.comclass UnifiedFreeList 961060SN/A{ 971060SN/A private: 989919Ssteve.reinhardt@amd.com 999919Ssteve.reinhardt@amd.com /** The object name, for DPRINTF. We have to declare this 1009919Ssteve.reinhardt@amd.com * explicitly because Scoreboard is not a SimObject. */ 1019919Ssteve.reinhardt@amd.com const std::string _name; 1029919Ssteve.reinhardt@amd.com 1031060SN/A /** The list of free integer registers. */ 1049919Ssteve.reinhardt@amd.com SimpleFreeList intList; 1051060SN/A 1061060SN/A /** The list of free floating point registers. */ 1079919Ssteve.reinhardt@amd.com SimpleFreeList floatList; 1081060SN/A 1099919Ssteve.reinhardt@amd.com /** 1109919Ssteve.reinhardt@amd.com * The register file object is used only to distinguish integer 1119919Ssteve.reinhardt@amd.com * from floating-point physical register indices. 1129919Ssteve.reinhardt@amd.com */ 1139919Ssteve.reinhardt@amd.com PhysRegFile *regFile; 1141060SN/A 1159919Ssteve.reinhardt@amd.com /* 1169919Ssteve.reinhardt@amd.com * We give UnifiedRenameMap internal access so it can get at the 1179919Ssteve.reinhardt@amd.com * internal per-class free lists and associate those with its 1189919Ssteve.reinhardt@amd.com * per-class rename maps. See UnifiedRenameMap::init(). 1199919Ssteve.reinhardt@amd.com */ 1209919Ssteve.reinhardt@amd.com friend class UnifiedRenameMap; 1211060SN/A 1221060SN/A public: 1232292SN/A /** Constructs a free list. 1242292SN/A * @param _numPhysicalIntRegs Number of physical integer registers. 1259919Ssteve.reinhardt@amd.com * @param reservedIntRegs Number of integer registers already 1269919Ssteve.reinhardt@amd.com * used by initial mappings. 1272292SN/A * @param _numPhysicalFloatRegs Number of physical fp registers. 1289919Ssteve.reinhardt@amd.com * @param reservedFloatRegs Number of fp registers already 1299919Ssteve.reinhardt@amd.com * used by initial mappings. 1302292SN/A */ 1319919Ssteve.reinhardt@amd.com UnifiedFreeList(const std::string &_my_name, PhysRegFile *_regFile); 1321060SN/A 1332292SN/A /** Gives the name of the freelist. */ 1349919Ssteve.reinhardt@amd.com std::string name() const { return _name; }; 1352292SN/A 1362292SN/A /** Gets a free integer register. */ 1379919Ssteve.reinhardt@amd.com PhysRegIndex getIntReg() { return intList.getReg(); } 1381060SN/A 1392292SN/A /** Gets a free fp register. */ 1409919Ssteve.reinhardt@amd.com PhysRegIndex getFloatReg() { return floatList.getReg(); } 1411060SN/A 1422292SN/A /** Adds a register back to the free list. */ 1439919Ssteve.reinhardt@amd.com void addReg(PhysRegIndex freed_reg); 1441060SN/A 1452292SN/A /** Adds an integer register back to the free list. */ 1469919Ssteve.reinhardt@amd.com void addIntReg(PhysRegIndex freed_reg) { intList.addReg(freed_reg); } 1471060SN/A 1482292SN/A /** Adds a fp register back to the free list. */ 1499919Ssteve.reinhardt@amd.com void addFloatReg(PhysRegIndex freed_reg) { floatList.addReg(freed_reg); } 1501060SN/A 1512292SN/A /** Checks if there are any free integer registers. */ 1529919Ssteve.reinhardt@amd.com bool hasFreeIntRegs() const { return intList.hasFreeRegs(); } 1531060SN/A 1542292SN/A /** Checks if there are any free fp registers. */ 1559919Ssteve.reinhardt@amd.com bool hasFreeFloatRegs() const { return floatList.hasFreeRegs(); } 1561060SN/A 1572292SN/A /** Returns the number of free integer registers. */ 1589919Ssteve.reinhardt@amd.com unsigned numFreeIntRegs() const { return intList.numFreeRegs(); } 1591060SN/A 1602292SN/A /** Returns the number of free fp registers. */ 1619919Ssteve.reinhardt@amd.com unsigned numFreeFloatRegs() const { return floatList.numFreeRegs(); } 1621060SN/A}; 1631060SN/A 1641060SN/Ainline void 1659919Ssteve.reinhardt@amd.comUnifiedFreeList::addReg(PhysRegIndex freed_reg) 1661060SN/A{ 1672292SN/A DPRINTF(FreeList,"Freeing register %i.\n", freed_reg); 1681060SN/A //Might want to add in a check for whether or not this register is 1691060SN/A //already in there. A bit vector or something similar would be useful. 1709919Ssteve.reinhardt@amd.com if (regFile->isIntPhysReg(freed_reg)) { 1719919Ssteve.reinhardt@amd.com intList.addReg(freed_reg); 1729919Ssteve.reinhardt@amd.com } else { 1739919Ssteve.reinhardt@amd.com assert(regFile->isFloatPhysReg(freed_reg)); 1749919Ssteve.reinhardt@amd.com floatList.addReg(freed_reg); 1751060SN/A } 1765362Sksewell@umich.edu 1775364Sksewell@umich.edu // These assert conditions ensure that the number of free 1785364Sksewell@umich.edu // registers are not more than the # of total Physical Registers. 1795364Sksewell@umich.edu // If this were false, it would mean that registers 1805364Sksewell@umich.edu // have been freed twice, overflowing the free register 1815364Sksewell@umich.edu // pool and potentially crashing SMT workloads. 1825364Sksewell@umich.edu // ---- 1835364Sksewell@umich.edu // Comment out for now so as to not potentially break 1845364Sksewell@umich.edu // CMP and single-threaded workloads 1855364Sksewell@umich.edu // ---- 1865364Sksewell@umich.edu // assert(freeIntRegs.size() <= numPhysicalIntRegs); 1875364Sksewell@umich.edu // assert(freeFloatRegs.size() <= numPhysicalFloatRegs); 1881060SN/A} 1891060SN/A 1901060SN/A 1912292SN/A#endif // __CPU_O3_FREE_LIST_HH__ 192