store_set.cc revision 8519
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" 358232Snate@binkert.org#include "debug/StoreSet.hh" 361061SN/A 378519SAli.Saidi@ARM.comStoreSet::StoreSet(uint64_t clear_period, int _SSIT_size, int _LFST_size) 388519SAli.Saidi@ARM.com : clearPeriod(clear_period), SSITSize(_SSIT_size), LFSTSize(_LFST_size) 391061SN/A{ 401061SN/A DPRINTF(StoreSet, "StoreSet: Creating store set object.\n"); 411062SN/A DPRINTF(StoreSet, "StoreSet: SSIT size: %i, LFST size: %i.\n", 422292SN/A SSITSize, LFSTSize); 431061SN/A 442348SN/A if (!isPowerOf2(SSITSize)) { 452348SN/A fatal("Invalid SSIT size!\n"); 462348SN/A } 472348SN/A 482292SN/A SSIT.resize(SSITSize); 491061SN/A 502292SN/A validSSIT.resize(SSITSize); 511061SN/A 522292SN/A for (int i = 0; i < SSITSize; ++i) 531061SN/A validSSIT[i] = false; 541061SN/A 552348SN/A if (!isPowerOf2(LFSTSize)) { 562348SN/A fatal("Invalid LFST size!\n"); 572348SN/A } 582348SN/A 592292SN/A LFST.resize(LFSTSize); 601061SN/A 612292SN/A validLFST.resize(LFSTSize); 621061SN/A 632292SN/A for (int i = 0; i < LFSTSize; ++i) { 641061SN/A validLFST[i] = false; 652292SN/A LFST[i] = 0; 661061SN/A } 671061SN/A 682292SN/A indexMask = SSITSize - 1; 691061SN/A 702292SN/A offsetBits = 2; 718519SAli.Saidi@ARM.com 728519SAli.Saidi@ARM.com memOpsPred = 0; 731061SN/A} 741061SN/A 752292SN/AStoreSet::~StoreSet() 762292SN/A{ 772292SN/A} 782292SN/A 792292SN/Avoid 808519SAli.Saidi@ARM.comStoreSet::init(uint64_t clear_period, int _SSIT_size, int _LFST_size) 812292SN/A{ 822292SN/A SSITSize = _SSIT_size; 832292SN/A LFSTSize = _LFST_size; 848519SAli.Saidi@ARM.com clearPeriod = clear_period; 852292SN/A 862292SN/A DPRINTF(StoreSet, "StoreSet: Creating store set object.\n"); 872292SN/A DPRINTF(StoreSet, "StoreSet: SSIT size: %i, LFST size: %i.\n", 882292SN/A SSITSize, LFSTSize); 892292SN/A 902292SN/A SSIT.resize(SSITSize); 912292SN/A 922292SN/A validSSIT.resize(SSITSize); 932292SN/A 942292SN/A for (int i = 0; i < SSITSize; ++i) 952292SN/A validSSIT[i] = false; 962292SN/A 972292SN/A LFST.resize(LFSTSize); 982292SN/A 992292SN/A validLFST.resize(LFSTSize); 1002292SN/A 1012292SN/A for (int i = 0; i < LFSTSize; ++i) { 1022292SN/A validLFST[i] = false; 1032292SN/A LFST[i] = 0; 1042292SN/A } 1052292SN/A 1062292SN/A indexMask = SSITSize - 1; 1072292SN/A 1082292SN/A offsetBits = 2; 1098519SAli.Saidi@ARM.com 1108519SAli.Saidi@ARM.com memOpsPred = 0; 1112292SN/A} 1122292SN/A 1132292SN/A 1141061SN/Avoid 1151062SN/AStoreSet::violation(Addr store_PC, Addr load_PC) 1161061SN/A{ 1171061SN/A int load_index = calcIndex(load_PC); 1181061SN/A int store_index = calcIndex(store_PC); 1191061SN/A 1202292SN/A assert(load_index < SSITSize && store_index < SSITSize); 1211062SN/A 1221061SN/A bool valid_load_SSID = validSSIT[load_index]; 1231061SN/A bool valid_store_SSID = validSSIT[store_index]; 1241061SN/A 1251061SN/A if (!valid_load_SSID && !valid_store_SSID) { 1261061SN/A // Calculate a new SSID here. 1271061SN/A SSID new_set = calcSSID(load_PC); 1281061SN/A 1291061SN/A validSSIT[load_index] = true; 1301061SN/A 1311061SN/A SSIT[load_index] = new_set; 1321061SN/A 1331061SN/A validSSIT[store_index] = true; 1341061SN/A 1351061SN/A SSIT[store_index] = new_set; 1361061SN/A 1372292SN/A assert(new_set < LFSTSize); 1381062SN/A 1391062SN/A DPRINTF(StoreSet, "StoreSet: Neither load nor store had a valid " 1401062SN/A "storeset, creating a new one: %i for load %#x, store %#x\n", 1411062SN/A new_set, load_PC, store_PC); 1421061SN/A } else if (valid_load_SSID && !valid_store_SSID) { 1431061SN/A SSID load_SSID = SSIT[load_index]; 1441061SN/A 1451061SN/A validSSIT[store_index] = true; 1461061SN/A 1471061SN/A SSIT[store_index] = load_SSID; 1481061SN/A 1492292SN/A assert(load_SSID < LFSTSize); 1501062SN/A 1511062SN/A DPRINTF(StoreSet, "StoreSet: Load had a valid store set. Adding " 1521062SN/A "store to that set: %i for load %#x, store %#x\n", 1531062SN/A load_SSID, load_PC, store_PC); 1541061SN/A } else if (!valid_load_SSID && valid_store_SSID) { 1551061SN/A SSID store_SSID = SSIT[store_index]; 1561061SN/A 1571061SN/A validSSIT[load_index] = true; 1581061SN/A 1591061SN/A SSIT[load_index] = store_SSID; 1601061SN/A 1611062SN/A DPRINTF(StoreSet, "StoreSet: Store had a valid store set: %i for " 1621062SN/A "load %#x, store %#x\n", 1631062SN/A store_SSID, load_PC, store_PC); 1641061SN/A } else { 1651061SN/A SSID load_SSID = SSIT[load_index]; 1661061SN/A SSID store_SSID = SSIT[store_index]; 1671061SN/A 1682292SN/A assert(load_SSID < LFSTSize && store_SSID < LFSTSize); 1691062SN/A 1702292SN/A // The store set with the lower number wins 1712292SN/A if (store_SSID > load_SSID) { 1721061SN/A SSIT[store_index] = load_SSID; 1731061SN/A 1742292SN/A DPRINTF(StoreSet, "StoreSet: Load had smaller store set: %i; " 1751062SN/A "for load %#x, store %#x\n", 1761062SN/A load_SSID, load_PC, store_PC); 1771061SN/A } else { 1781061SN/A SSIT[load_index] = store_SSID; 1791061SN/A 1802292SN/A DPRINTF(StoreSet, "StoreSet: Store had smaller store set: %i; " 1811062SN/A "for load %#x, store %#x\n", 1821062SN/A store_SSID, load_PC, store_PC); 1831061SN/A } 1841061SN/A } 1851061SN/A} 1861061SN/A 1871061SN/Avoid 1888519SAli.Saidi@ARM.comStoreSet::checkClear() 1898519SAli.Saidi@ARM.com{ 1908519SAli.Saidi@ARM.com memOpsPred++; 1918519SAli.Saidi@ARM.com if (memOpsPred > clearPeriod) { 1928519SAli.Saidi@ARM.com DPRINTF(StoreSet, "Wiping predictor state beacuse %d ld/st executed\n", 1938519SAli.Saidi@ARM.com clearPeriod); 1948519SAli.Saidi@ARM.com memOpsPred = 0; 1958519SAli.Saidi@ARM.com clear(); 1968519SAli.Saidi@ARM.com } 1978519SAli.Saidi@ARM.com} 1988519SAli.Saidi@ARM.com 1998519SAli.Saidi@ARM.comvoid 2001061SN/AStoreSet::insertLoad(Addr load_PC, InstSeqNum load_seq_num) 2011061SN/A{ 2028519SAli.Saidi@ARM.com checkClear(); 2031061SN/A // Does nothing. 2041061SN/A return; 2051061SN/A} 2061061SN/A 2071061SN/Avoid 2086221Snate@binkert.orgStoreSet::insertStore(Addr store_PC, InstSeqNum store_seq_num, ThreadID tid) 2091061SN/A{ 2101061SN/A int index = calcIndex(store_PC); 2111061SN/A 2121061SN/A int store_SSID; 2131061SN/A 2148519SAli.Saidi@ARM.com checkClear(); 2152292SN/A assert(index < SSITSize); 2161062SN/A 2171061SN/A if (!validSSIT[index]) { 2181061SN/A // Do nothing if there's no valid entry. 2191061SN/A return; 2201061SN/A } else { 2211061SN/A store_SSID = SSIT[index]; 2221061SN/A 2232292SN/A assert(store_SSID < LFSTSize); 2241061SN/A 2251061SN/A // Update the last store that was fetched with the current one. 2261061SN/A LFST[store_SSID] = store_seq_num; 2271062SN/A 2281062SN/A validLFST[store_SSID] = 1; 2291062SN/A 2302292SN/A storeList[store_seq_num] = store_SSID; 2312292SN/A 2321062SN/A DPRINTF(StoreSet, "Store %#x updated the LFST, SSID: %i\n", 2331062SN/A store_PC, store_SSID); 2341061SN/A } 2351061SN/A} 2361061SN/A 2371061SN/AInstSeqNum 2381061SN/AStoreSet::checkInst(Addr PC) 2391061SN/A{ 2401061SN/A int index = calcIndex(PC); 2411061SN/A 2421061SN/A int inst_SSID; 2431061SN/A 2442292SN/A assert(index < SSITSize); 2451062SN/A 2461061SN/A if (!validSSIT[index]) { 2471062SN/A DPRINTF(StoreSet, "Inst %#x with index %i had no SSID\n", 2481062SN/A PC, index); 2491062SN/A 2501061SN/A // Return 0 if there's no valid entry. 2511061SN/A return 0; 2521061SN/A } else { 2531061SN/A inst_SSID = SSIT[index]; 2541061SN/A 2552292SN/A assert(inst_SSID < LFSTSize); 2561061SN/A 2571061SN/A if (!validLFST[inst_SSID]) { 2581062SN/A 2591062SN/A DPRINTF(StoreSet, "Inst %#x with index %i and SSID %i had no " 2601062SN/A "dependency\n", PC, index, inst_SSID); 2611062SN/A 2621061SN/A return 0; 2631061SN/A } else { 2641062SN/A DPRINTF(StoreSet, "Inst %#x with index %i and SSID %i had LFST " 2651062SN/A "inum of %i\n", PC, index, inst_SSID, LFST[inst_SSID]); 2661062SN/A 2671061SN/A return LFST[inst_SSID]; 2681061SN/A } 2691061SN/A } 2701061SN/A} 2711061SN/A 2721061SN/Avoid 2731061SN/AStoreSet::issued(Addr issued_PC, InstSeqNum issued_seq_num, bool is_store) 2741061SN/A{ 2751061SN/A // This only is updated upon a store being issued. 2761061SN/A if (!is_store) { 2771061SN/A return; 2781061SN/A } 2791061SN/A 2801061SN/A int index = calcIndex(issued_PC); 2811061SN/A 2821061SN/A int store_SSID; 2831061SN/A 2842292SN/A assert(index < SSITSize); 2852292SN/A 2862292SN/A SeqNumMapIt store_list_it = storeList.find(issued_seq_num); 2872292SN/A 2882292SN/A if (store_list_it != storeList.end()) { 2892292SN/A storeList.erase(store_list_it); 2902292SN/A } 2911062SN/A 2921061SN/A // Make sure the SSIT still has a valid entry for the issued store. 2931062SN/A if (!validSSIT[index]) { 2941062SN/A return; 2951062SN/A } 2961061SN/A 2971061SN/A store_SSID = SSIT[index]; 2981061SN/A 2992292SN/A assert(store_SSID < LFSTSize); 3001062SN/A 3011061SN/A // If the last fetched store in the store set refers to the store that 3021061SN/A // was just issued, then invalidate the entry. 3031061SN/A if (validLFST[store_SSID] && LFST[store_SSID] == issued_seq_num) { 3041062SN/A DPRINTF(StoreSet, "StoreSet: store invalidated itself in LFST.\n"); 3051061SN/A validLFST[store_SSID] = false; 3061061SN/A } 3071061SN/A} 3081061SN/A 3091061SN/Avoid 3106221Snate@binkert.orgStoreSet::squash(InstSeqNum squashed_num, ThreadID tid) 3111061SN/A{ 3121062SN/A DPRINTF(StoreSet, "StoreSet: Squashing until inum %i\n", 3131062SN/A squashed_num); 3141061SN/A 3152292SN/A int idx; 3162292SN/A SeqNumMapIt store_list_it = storeList.begin(); 3172292SN/A 3182292SN/A //@todo:Fix to only delete from correct thread 3192292SN/A while (!storeList.empty()) { 3202292SN/A idx = (*store_list_it).second; 3212292SN/A 3222292SN/A if ((*store_list_it).first <= squashed_num) { 3232292SN/A break; 3242292SN/A } 3252292SN/A 3262292SN/A bool younger = LFST[idx] > squashed_num; 3272292SN/A 3282292SN/A if (validLFST[idx] && younger) { 3292292SN/A DPRINTF(StoreSet, "Squashed [sn:%lli]\n", LFST[idx]); 3302292SN/A validLFST[idx] = false; 3312292SN/A 3322292SN/A storeList.erase(store_list_it++); 3332292SN/A } else if (!validLFST[idx] && younger) { 3342292SN/A storeList.erase(store_list_it++); 3351061SN/A } 3361061SN/A } 3371061SN/A} 3381061SN/A 3391061SN/Avoid 3401061SN/AStoreSet::clear() 3411061SN/A{ 3422292SN/A for (int i = 0; i < SSITSize; ++i) { 3431061SN/A validSSIT[i] = false; 3441061SN/A } 3451061SN/A 3462292SN/A for (int i = 0; i < LFSTSize; ++i) { 3471061SN/A validLFST[i] = false; 3481061SN/A } 3492292SN/A 3502292SN/A storeList.clear(); 3511061SN/A} 3522348SN/A 3532348SN/Avoid 3542348SN/AStoreSet::dump() 3552348SN/A{ 3562348SN/A cprintf("storeList.size(): %i\n", storeList.size()); 3572348SN/A SeqNumMapIt store_list_it = storeList.begin(); 3582348SN/A 3592348SN/A int num = 0; 3602348SN/A 3612348SN/A while (store_list_it != storeList.end()) { 3622348SN/A cprintf("%i: [sn:%lli] SSID:%i\n", 3632348SN/A num, (*store_list_it).first, (*store_list_it).second); 3642348SN/A num++; 3652348SN/A store_list_it++; 3662348SN/A } 3672348SN/A} 368