store_set.cc revision 2678
11689SN/A/* 22329SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan 31689SN/A * All rights reserved. 41689SN/A * 51689SN/A * Redistribution and use in source and binary forms, with or without 61689SN/A * modification, are permitted provided that the following conditions are 71689SN/A * met: redistributions of source code must retain the above copyright 81689SN/A * notice, this list of conditions and the following disclaimer; 91689SN/A * redistributions in binary form must reproduce the above copyright 101689SN/A * notice, this list of conditions and the following disclaimer in the 111689SN/A * documentation and/or other materials provided with the distribution; 121689SN/A * neither the name of the copyright holders nor the names of its 131689SN/A * contributors may be used to endorse or promote products derived from 141689SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Kevin Lim 291689SN/A */ 301689SN/A 312348SN/A#include "base/intmath.hh" 322678Sktlim@umich.edu#include "base/misc.hh" 331689SN/A#include "base/trace.hh" 341717SN/A#include "cpu/o3/store_set.hh" 351061SN/A 361061SN/AStoreSet::StoreSet(int _SSIT_size, int _LFST_size) 372292SN/A : SSITSize(_SSIT_size), LFSTSize(_LFST_size) 381061SN/A{ 391061SN/A DPRINTF(StoreSet, "StoreSet: Creating store set object.\n"); 401062SN/A DPRINTF(StoreSet, "StoreSet: SSIT size: %i, LFST size: %i.\n", 412292SN/A SSITSize, LFSTSize); 421061SN/A 432348SN/A if (!isPowerOf2(SSITSize)) { 442348SN/A fatal("Invalid SSIT size!\n"); 452348SN/A } 462348SN/A 472292SN/A SSIT.resize(SSITSize); 481061SN/A 492292SN/A validSSIT.resize(SSITSize); 501061SN/A 512292SN/A for (int i = 0; i < SSITSize; ++i) 521061SN/A validSSIT[i] = false; 531061SN/A 542348SN/A if (!isPowerOf2(LFSTSize)) { 552348SN/A fatal("Invalid LFST size!\n"); 562348SN/A } 572348SN/A 582292SN/A LFST.resize(LFSTSize); 591061SN/A 602292SN/A validLFST.resize(LFSTSize); 611061SN/A 622292SN/A for (int i = 0; i < LFSTSize; ++i) { 631061SN/A validLFST[i] = false; 642292SN/A LFST[i] = 0; 651061SN/A } 661061SN/A 672292SN/A indexMask = SSITSize - 1; 681061SN/A 692292SN/A offsetBits = 2; 701061SN/A} 711061SN/A 722292SN/AStoreSet::~StoreSet() 732292SN/A{ 742292SN/A} 752292SN/A 762292SN/Avoid 772292SN/AStoreSet::init(int _SSIT_size, int _LFST_size) 782292SN/A{ 792292SN/A SSITSize = _SSIT_size; 802292SN/A LFSTSize = _LFST_size; 812292SN/A 822292SN/A DPRINTF(StoreSet, "StoreSet: Creating store set object.\n"); 832292SN/A DPRINTF(StoreSet, "StoreSet: SSIT size: %i, LFST size: %i.\n", 842292SN/A SSITSize, LFSTSize); 852292SN/A 862292SN/A SSIT.resize(SSITSize); 872292SN/A 882292SN/A validSSIT.resize(SSITSize); 892292SN/A 902292SN/A for (int i = 0; i < SSITSize; ++i) 912292SN/A validSSIT[i] = false; 922292SN/A 932292SN/A LFST.resize(LFSTSize); 942292SN/A 952292SN/A validLFST.resize(LFSTSize); 962292SN/A 972292SN/A for (int i = 0; i < LFSTSize; ++i) { 982292SN/A validLFST[i] = false; 992292SN/A LFST[i] = 0; 1002292SN/A } 1012292SN/A 1022292SN/A indexMask = SSITSize - 1; 1032292SN/A 1042292SN/A offsetBits = 2; 1052292SN/A} 1062292SN/A 1072292SN/A 1081061SN/Avoid 1091062SN/AStoreSet::violation(Addr store_PC, Addr load_PC) 1101061SN/A{ 1111061SN/A int load_index = calcIndex(load_PC); 1121061SN/A int store_index = calcIndex(store_PC); 1131061SN/A 1142292SN/A assert(load_index < SSITSize && store_index < SSITSize); 1151062SN/A 1161061SN/A bool valid_load_SSID = validSSIT[load_index]; 1171061SN/A bool valid_store_SSID = validSSIT[store_index]; 1181061SN/A 1191061SN/A if (!valid_load_SSID && !valid_store_SSID) { 1201061SN/A // Calculate a new SSID here. 1211061SN/A SSID new_set = calcSSID(load_PC); 1221061SN/A 1231061SN/A validSSIT[load_index] = true; 1241061SN/A 1251061SN/A SSIT[load_index] = new_set; 1261061SN/A 1271061SN/A validSSIT[store_index] = true; 1281061SN/A 1291061SN/A SSIT[store_index] = new_set; 1301061SN/A 1312292SN/A assert(new_set < LFSTSize); 1321062SN/A 1331062SN/A DPRINTF(StoreSet, "StoreSet: Neither load nor store had a valid " 1341062SN/A "storeset, creating a new one: %i for load %#x, store %#x\n", 1351062SN/A new_set, load_PC, store_PC); 1361061SN/A } else if (valid_load_SSID && !valid_store_SSID) { 1371061SN/A SSID load_SSID = SSIT[load_index]; 1381061SN/A 1391061SN/A validSSIT[store_index] = true; 1401061SN/A 1411061SN/A SSIT[store_index] = load_SSID; 1421061SN/A 1432292SN/A assert(load_SSID < LFSTSize); 1441062SN/A 1451062SN/A DPRINTF(StoreSet, "StoreSet: Load had a valid store set. Adding " 1461062SN/A "store to that set: %i for load %#x, store %#x\n", 1471062SN/A load_SSID, load_PC, store_PC); 1481061SN/A } else if (!valid_load_SSID && valid_store_SSID) { 1491061SN/A SSID store_SSID = SSIT[store_index]; 1501061SN/A 1511061SN/A validSSIT[load_index] = true; 1521061SN/A 1531061SN/A SSIT[load_index] = store_SSID; 1541061SN/A 1551062SN/A DPRINTF(StoreSet, "StoreSet: Store had a valid store set: %i for " 1561062SN/A "load %#x, store %#x\n", 1571062SN/A store_SSID, load_PC, store_PC); 1581061SN/A } else { 1591061SN/A SSID load_SSID = SSIT[load_index]; 1601061SN/A SSID store_SSID = SSIT[store_index]; 1611061SN/A 1622292SN/A assert(load_SSID < LFSTSize && store_SSID < LFSTSize); 1631062SN/A 1642292SN/A // The store set with the lower number wins 1652292SN/A if (store_SSID > load_SSID) { 1661061SN/A SSIT[store_index] = load_SSID; 1671061SN/A 1682292SN/A DPRINTF(StoreSet, "StoreSet: Load had smaller store set: %i; " 1691062SN/A "for load %#x, store %#x\n", 1701062SN/A load_SSID, load_PC, store_PC); 1711061SN/A } else { 1721061SN/A SSIT[load_index] = store_SSID; 1731061SN/A 1742292SN/A DPRINTF(StoreSet, "StoreSet: Store had smaller store set: %i; " 1751062SN/A "for load %#x, store %#x\n", 1761062SN/A store_SSID, load_PC, store_PC); 1771061SN/A } 1781061SN/A } 1791061SN/A} 1801061SN/A 1811061SN/Avoid 1821061SN/AStoreSet::insertLoad(Addr load_PC, InstSeqNum load_seq_num) 1831061SN/A{ 1841061SN/A // Does nothing. 1851061SN/A return; 1861061SN/A} 1871061SN/A 1881061SN/Avoid 1892292SN/AStoreSet::insertStore(Addr store_PC, InstSeqNum store_seq_num, 1902292SN/A unsigned tid) 1911061SN/A{ 1921061SN/A int index = calcIndex(store_PC); 1931061SN/A 1941061SN/A int store_SSID; 1951061SN/A 1962292SN/A assert(index < SSITSize); 1971062SN/A 1981061SN/A if (!validSSIT[index]) { 1991061SN/A // Do nothing if there's no valid entry. 2001061SN/A return; 2011061SN/A } else { 2021061SN/A store_SSID = SSIT[index]; 2031061SN/A 2042292SN/A assert(store_SSID < LFSTSize); 2051061SN/A 2061061SN/A // Update the last store that was fetched with the current one. 2071061SN/A LFST[store_SSID] = store_seq_num; 2081062SN/A 2091062SN/A validLFST[store_SSID] = 1; 2101062SN/A 2112292SN/A storeList[store_seq_num] = store_SSID; 2122292SN/A 2131062SN/A DPRINTF(StoreSet, "Store %#x updated the LFST, SSID: %i\n", 2141062SN/A store_PC, store_SSID); 2151061SN/A } 2161061SN/A} 2171061SN/A 2181061SN/AInstSeqNum 2191061SN/AStoreSet::checkInst(Addr PC) 2201061SN/A{ 2211061SN/A int index = calcIndex(PC); 2221061SN/A 2231061SN/A int inst_SSID; 2241061SN/A 2252292SN/A assert(index < SSITSize); 2261062SN/A 2271061SN/A if (!validSSIT[index]) { 2281062SN/A DPRINTF(StoreSet, "Inst %#x with index %i had no SSID\n", 2291062SN/A PC, index); 2301062SN/A 2311061SN/A // Return 0 if there's no valid entry. 2321061SN/A return 0; 2331061SN/A } else { 2341061SN/A inst_SSID = SSIT[index]; 2351061SN/A 2362292SN/A assert(inst_SSID < LFSTSize); 2371061SN/A 2381061SN/A if (!validLFST[inst_SSID]) { 2391062SN/A 2401062SN/A DPRINTF(StoreSet, "Inst %#x with index %i and SSID %i had no " 2411062SN/A "dependency\n", PC, index, inst_SSID); 2421062SN/A 2431061SN/A return 0; 2441061SN/A } else { 2451062SN/A DPRINTF(StoreSet, "Inst %#x with index %i and SSID %i had LFST " 2461062SN/A "inum of %i\n", PC, index, inst_SSID, LFST[inst_SSID]); 2471062SN/A 2481061SN/A return LFST[inst_SSID]; 2491061SN/A } 2501061SN/A } 2511061SN/A} 2521061SN/A 2531061SN/Avoid 2541061SN/AStoreSet::issued(Addr issued_PC, InstSeqNum issued_seq_num, bool is_store) 2551061SN/A{ 2561061SN/A // This only is updated upon a store being issued. 2571061SN/A if (!is_store) { 2581061SN/A return; 2591061SN/A } 2601061SN/A 2611061SN/A int index = calcIndex(issued_PC); 2621061SN/A 2631061SN/A int store_SSID; 2641061SN/A 2652292SN/A assert(index < SSITSize); 2662292SN/A 2672292SN/A SeqNumMapIt store_list_it = storeList.find(issued_seq_num); 2682292SN/A 2692292SN/A if (store_list_it != storeList.end()) { 2702292SN/A storeList.erase(store_list_it); 2712292SN/A } 2721062SN/A 2731061SN/A // Make sure the SSIT still has a valid entry for the issued store. 2741062SN/A if (!validSSIT[index]) { 2751062SN/A return; 2761062SN/A } 2771061SN/A 2781061SN/A store_SSID = SSIT[index]; 2791061SN/A 2802292SN/A assert(store_SSID < LFSTSize); 2811062SN/A 2821061SN/A // If the last fetched store in the store set refers to the store that 2831061SN/A // was just issued, then invalidate the entry. 2841061SN/A if (validLFST[store_SSID] && LFST[store_SSID] == issued_seq_num) { 2851062SN/A DPRINTF(StoreSet, "StoreSet: store invalidated itself in LFST.\n"); 2861061SN/A validLFST[store_SSID] = false; 2871061SN/A } 2881061SN/A} 2891061SN/A 2901061SN/Avoid 2912292SN/AStoreSet::squash(InstSeqNum squashed_num, unsigned tid) 2921061SN/A{ 2931062SN/A DPRINTF(StoreSet, "StoreSet: Squashing until inum %i\n", 2941062SN/A squashed_num); 2951061SN/A 2962292SN/A int idx; 2972292SN/A SeqNumMapIt store_list_it = storeList.begin(); 2982292SN/A 2992292SN/A //@todo:Fix to only delete from correct thread 3002292SN/A while (!storeList.empty()) { 3012292SN/A idx = (*store_list_it).second; 3022292SN/A 3032292SN/A if ((*store_list_it).first <= squashed_num) { 3042292SN/A break; 3052292SN/A } 3062292SN/A 3072292SN/A bool younger = LFST[idx] > squashed_num; 3082292SN/A 3092292SN/A if (validLFST[idx] && younger) { 3102292SN/A DPRINTF(StoreSet, "Squashed [sn:%lli]\n", LFST[idx]); 3112292SN/A validLFST[idx] = false; 3122292SN/A 3132292SN/A storeList.erase(store_list_it++); 3142292SN/A } else if (!validLFST[idx] && younger) { 3152292SN/A storeList.erase(store_list_it++); 3161061SN/A } 3171061SN/A } 3181061SN/A} 3191061SN/A 3201061SN/Avoid 3211061SN/AStoreSet::clear() 3221061SN/A{ 3232292SN/A for (int i = 0; i < SSITSize; ++i) { 3241061SN/A validSSIT[i] = false; 3251061SN/A } 3261061SN/A 3272292SN/A for (int i = 0; i < LFSTSize; ++i) { 3281061SN/A validLFST[i] = false; 3291061SN/A } 3302292SN/A 3312292SN/A storeList.clear(); 3321061SN/A} 3332348SN/A 3342348SN/Avoid 3352348SN/AStoreSet::dump() 3362348SN/A{ 3372348SN/A cprintf("storeList.size(): %i\n", storeList.size()); 3382348SN/A SeqNumMapIt store_list_it = storeList.begin(); 3392348SN/A 3402348SN/A int num = 0; 3412348SN/A 3422348SN/A while (store_list_it != storeList.end()) { 3432348SN/A cprintf("%i: [sn:%lli] SSID:%i\n", 3442348SN/A num, (*store_list_it).first, (*store_list_it).second); 3452348SN/A num++; 3462348SN/A store_list_it++; 3472348SN/A } 3482348SN/A} 349