store_set.cc revision 11793
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 3111793Sbrandon.potter@amd.com#include "cpu/o3/store_set.hh" 3211793Sbrandon.potter@amd.com 332348SN/A#include "base/intmath.hh" 342678Sktlim@umich.edu#include "base/misc.hh" 351689SN/A#include "base/trace.hh" 368232Snate@binkert.org#include "debug/StoreSet.hh" 371061SN/A 388519SAli.Saidi@ARM.comStoreSet::StoreSet(uint64_t clear_period, int _SSIT_size, int _LFST_size) 398519SAli.Saidi@ARM.com : clearPeriod(clear_period), SSITSize(_SSIT_size), LFSTSize(_LFST_size) 401061SN/A{ 411061SN/A DPRINTF(StoreSet, "StoreSet: Creating store set object.\n"); 421062SN/A DPRINTF(StoreSet, "StoreSet: SSIT size: %i, LFST size: %i.\n", 432292SN/A SSITSize, LFSTSize); 441061SN/A 452348SN/A if (!isPowerOf2(SSITSize)) { 462348SN/A fatal("Invalid SSIT size!\n"); 472348SN/A } 482348SN/A 492292SN/A SSIT.resize(SSITSize); 501061SN/A 512292SN/A validSSIT.resize(SSITSize); 521061SN/A 532292SN/A for (int i = 0; i < SSITSize; ++i) 541061SN/A validSSIT[i] = false; 551061SN/A 562348SN/A if (!isPowerOf2(LFSTSize)) { 572348SN/A fatal("Invalid LFST size!\n"); 582348SN/A } 592348SN/A 602292SN/A LFST.resize(LFSTSize); 611061SN/A 622292SN/A validLFST.resize(LFSTSize); 631061SN/A 642292SN/A for (int i = 0; i < LFSTSize; ++i) { 651061SN/A validLFST[i] = false; 662292SN/A LFST[i] = 0; 671061SN/A } 681061SN/A 692292SN/A indexMask = SSITSize - 1; 701061SN/A 712292SN/A offsetBits = 2; 728519SAli.Saidi@ARM.com 738519SAli.Saidi@ARM.com memOpsPred = 0; 741061SN/A} 751061SN/A 762292SN/AStoreSet::~StoreSet() 772292SN/A{ 782292SN/A} 792292SN/A 802292SN/Avoid 818519SAli.Saidi@ARM.comStoreSet::init(uint64_t clear_period, int _SSIT_size, int _LFST_size) 822292SN/A{ 832292SN/A SSITSize = _SSIT_size; 842292SN/A LFSTSize = _LFST_size; 858519SAli.Saidi@ARM.com clearPeriod = clear_period; 862292SN/A 872292SN/A DPRINTF(StoreSet, "StoreSet: Creating store set object.\n"); 882292SN/A DPRINTF(StoreSet, "StoreSet: SSIT size: %i, LFST size: %i.\n", 892292SN/A SSITSize, LFSTSize); 902292SN/A 912292SN/A SSIT.resize(SSITSize); 922292SN/A 932292SN/A validSSIT.resize(SSITSize); 942292SN/A 952292SN/A for (int i = 0; i < SSITSize; ++i) 962292SN/A validSSIT[i] = false; 972292SN/A 982292SN/A LFST.resize(LFSTSize); 992292SN/A 1002292SN/A validLFST.resize(LFSTSize); 1012292SN/A 1022292SN/A for (int i = 0; i < LFSTSize; ++i) { 1032292SN/A validLFST[i] = false; 1042292SN/A LFST[i] = 0; 1052292SN/A } 1062292SN/A 1072292SN/A indexMask = SSITSize - 1; 1082292SN/A 1092292SN/A offsetBits = 2; 1108519SAli.Saidi@ARM.com 1118519SAli.Saidi@ARM.com memOpsPred = 0; 1122292SN/A} 1132292SN/A 1142292SN/A 1151061SN/Avoid 1161062SN/AStoreSet::violation(Addr store_PC, Addr load_PC) 1171061SN/A{ 1181061SN/A int load_index = calcIndex(load_PC); 1191061SN/A int store_index = calcIndex(store_PC); 1201061SN/A 1212292SN/A assert(load_index < SSITSize && store_index < SSITSize); 1221062SN/A 1231061SN/A bool valid_load_SSID = validSSIT[load_index]; 1241061SN/A bool valid_store_SSID = validSSIT[store_index]; 1251061SN/A 1261061SN/A if (!valid_load_SSID && !valid_store_SSID) { 1271061SN/A // Calculate a new SSID here. 1281061SN/A SSID new_set = calcSSID(load_PC); 1291061SN/A 1301061SN/A validSSIT[load_index] = true; 1311061SN/A 1321061SN/A SSIT[load_index] = new_set; 1331061SN/A 1341061SN/A validSSIT[store_index] = true; 1351061SN/A 1361061SN/A SSIT[store_index] = new_set; 1371061SN/A 1382292SN/A assert(new_set < LFSTSize); 1391062SN/A 1401062SN/A DPRINTF(StoreSet, "StoreSet: Neither load nor store had a valid " 1411062SN/A "storeset, creating a new one: %i for load %#x, store %#x\n", 1421062SN/A new_set, load_PC, store_PC); 1431061SN/A } else if (valid_load_SSID && !valid_store_SSID) { 1441061SN/A SSID load_SSID = SSIT[load_index]; 1451061SN/A 1461061SN/A validSSIT[store_index] = true; 1471061SN/A 1481061SN/A SSIT[store_index] = load_SSID; 1491061SN/A 1502292SN/A assert(load_SSID < LFSTSize); 1511062SN/A 1521062SN/A DPRINTF(StoreSet, "StoreSet: Load had a valid store set. Adding " 1531062SN/A "store to that set: %i for load %#x, store %#x\n", 1541062SN/A load_SSID, load_PC, store_PC); 1551061SN/A } else if (!valid_load_SSID && valid_store_SSID) { 1561061SN/A SSID store_SSID = SSIT[store_index]; 1571061SN/A 1581061SN/A validSSIT[load_index] = true; 1591061SN/A 1601061SN/A SSIT[load_index] = store_SSID; 1611061SN/A 1621062SN/A DPRINTF(StoreSet, "StoreSet: Store had a valid store set: %i for " 1631062SN/A "load %#x, store %#x\n", 1641062SN/A store_SSID, load_PC, store_PC); 1651061SN/A } else { 1661061SN/A SSID load_SSID = SSIT[load_index]; 1671061SN/A SSID store_SSID = SSIT[store_index]; 1681061SN/A 1692292SN/A assert(load_SSID < LFSTSize && store_SSID < LFSTSize); 1701062SN/A 1712292SN/A // The store set with the lower number wins 1722292SN/A if (store_SSID > load_SSID) { 1731061SN/A SSIT[store_index] = load_SSID; 1741061SN/A 1752292SN/A DPRINTF(StoreSet, "StoreSet: Load had smaller store set: %i; " 1761062SN/A "for load %#x, store %#x\n", 1771062SN/A load_SSID, load_PC, store_PC); 1781061SN/A } else { 1791061SN/A SSIT[load_index] = store_SSID; 1801061SN/A 1812292SN/A DPRINTF(StoreSet, "StoreSet: Store had smaller store set: %i; " 1821062SN/A "for load %#x, store %#x\n", 1831062SN/A store_SSID, load_PC, store_PC); 1841061SN/A } 1851061SN/A } 1861061SN/A} 1871061SN/A 1881061SN/Avoid 1898519SAli.Saidi@ARM.comStoreSet::checkClear() 1908519SAli.Saidi@ARM.com{ 1918519SAli.Saidi@ARM.com memOpsPred++; 1928519SAli.Saidi@ARM.com if (memOpsPred > clearPeriod) { 1938519SAli.Saidi@ARM.com DPRINTF(StoreSet, "Wiping predictor state beacuse %d ld/st executed\n", 1948519SAli.Saidi@ARM.com clearPeriod); 1958519SAli.Saidi@ARM.com memOpsPred = 0; 1968519SAli.Saidi@ARM.com clear(); 1978519SAli.Saidi@ARM.com } 1988519SAli.Saidi@ARM.com} 1998519SAli.Saidi@ARM.com 2008519SAli.Saidi@ARM.comvoid 2011061SN/AStoreSet::insertLoad(Addr load_PC, InstSeqNum load_seq_num) 2021061SN/A{ 2038519SAli.Saidi@ARM.com checkClear(); 2041061SN/A // Does nothing. 2051061SN/A return; 2061061SN/A} 2071061SN/A 2081061SN/Avoid 2096221Snate@binkert.orgStoreSet::insertStore(Addr store_PC, InstSeqNum store_seq_num, ThreadID tid) 2101061SN/A{ 2111061SN/A int index = calcIndex(store_PC); 2121061SN/A 2131061SN/A int store_SSID; 2141061SN/A 2158519SAli.Saidi@ARM.com checkClear(); 2162292SN/A assert(index < SSITSize); 2171062SN/A 2181061SN/A if (!validSSIT[index]) { 2191061SN/A // Do nothing if there's no valid entry. 2201061SN/A return; 2211061SN/A } else { 2221061SN/A store_SSID = SSIT[index]; 2231061SN/A 2242292SN/A assert(store_SSID < LFSTSize); 2251061SN/A 2261061SN/A // Update the last store that was fetched with the current one. 2271061SN/A LFST[store_SSID] = store_seq_num; 2281062SN/A 2291062SN/A validLFST[store_SSID] = 1; 2301062SN/A 2312292SN/A storeList[store_seq_num] = store_SSID; 2322292SN/A 2331062SN/A DPRINTF(StoreSet, "Store %#x updated the LFST, SSID: %i\n", 2341062SN/A store_PC, store_SSID); 2351061SN/A } 2361061SN/A} 2371061SN/A 2381061SN/AInstSeqNum 2391061SN/AStoreSet::checkInst(Addr PC) 2401061SN/A{ 2411061SN/A int index = calcIndex(PC); 2421061SN/A 2431061SN/A int inst_SSID; 2441061SN/A 2452292SN/A assert(index < SSITSize); 2461062SN/A 2471061SN/A if (!validSSIT[index]) { 2481062SN/A DPRINTF(StoreSet, "Inst %#x with index %i had no SSID\n", 2491062SN/A PC, index); 2501062SN/A 2511061SN/A // Return 0 if there's no valid entry. 2521061SN/A return 0; 2531061SN/A } else { 2541061SN/A inst_SSID = SSIT[index]; 2551061SN/A 2562292SN/A assert(inst_SSID < LFSTSize); 2571061SN/A 2581061SN/A if (!validLFST[inst_SSID]) { 2591062SN/A 2601062SN/A DPRINTF(StoreSet, "Inst %#x with index %i and SSID %i had no " 2611062SN/A "dependency\n", PC, index, inst_SSID); 2621062SN/A 2631061SN/A return 0; 2641061SN/A } else { 2651062SN/A DPRINTF(StoreSet, "Inst %#x with index %i and SSID %i had LFST " 2661062SN/A "inum of %i\n", PC, index, inst_SSID, LFST[inst_SSID]); 2671062SN/A 2681061SN/A return LFST[inst_SSID]; 2691061SN/A } 2701061SN/A } 2711061SN/A} 2721061SN/A 2731061SN/Avoid 2741061SN/AStoreSet::issued(Addr issued_PC, InstSeqNum issued_seq_num, bool is_store) 2751061SN/A{ 2761061SN/A // This only is updated upon a store being issued. 2771061SN/A if (!is_store) { 2781061SN/A return; 2791061SN/A } 2801061SN/A 2811061SN/A int index = calcIndex(issued_PC); 2821061SN/A 2831061SN/A int store_SSID; 2841061SN/A 2852292SN/A assert(index < SSITSize); 2862292SN/A 2872292SN/A SeqNumMapIt store_list_it = storeList.find(issued_seq_num); 2882292SN/A 2892292SN/A if (store_list_it != storeList.end()) { 2902292SN/A storeList.erase(store_list_it); 2912292SN/A } 2921062SN/A 2931061SN/A // Make sure the SSIT still has a valid entry for the issued store. 2941062SN/A if (!validSSIT[index]) { 2951062SN/A return; 2961062SN/A } 2971061SN/A 2981061SN/A store_SSID = SSIT[index]; 2991061SN/A 3002292SN/A assert(store_SSID < LFSTSize); 3011062SN/A 3021061SN/A // If the last fetched store in the store set refers to the store that 3031061SN/A // was just issued, then invalidate the entry. 3041061SN/A if (validLFST[store_SSID] && LFST[store_SSID] == issued_seq_num) { 3051062SN/A DPRINTF(StoreSet, "StoreSet: store invalidated itself in LFST.\n"); 3061061SN/A validLFST[store_SSID] = false; 3071061SN/A } 3081061SN/A} 3091061SN/A 3101061SN/Avoid 3116221Snate@binkert.orgStoreSet::squash(InstSeqNum squashed_num, ThreadID tid) 3121061SN/A{ 3131062SN/A DPRINTF(StoreSet, "StoreSet: Squashing until inum %i\n", 3141062SN/A squashed_num); 3151061SN/A 3162292SN/A int idx; 3172292SN/A SeqNumMapIt store_list_it = storeList.begin(); 3182292SN/A 3192292SN/A //@todo:Fix to only delete from correct thread 3202292SN/A while (!storeList.empty()) { 3212292SN/A idx = (*store_list_it).second; 3222292SN/A 3232292SN/A if ((*store_list_it).first <= squashed_num) { 3242292SN/A break; 3252292SN/A } 3262292SN/A 3272292SN/A bool younger = LFST[idx] > squashed_num; 3282292SN/A 3292292SN/A if (validLFST[idx] && younger) { 3302292SN/A DPRINTF(StoreSet, "Squashed [sn:%lli]\n", LFST[idx]); 3312292SN/A validLFST[idx] = false; 3322292SN/A 3332292SN/A storeList.erase(store_list_it++); 3342292SN/A } else if (!validLFST[idx] && younger) { 3352292SN/A storeList.erase(store_list_it++); 3361061SN/A } 3371061SN/A } 3381061SN/A} 3391061SN/A 3401061SN/Avoid 3411061SN/AStoreSet::clear() 3421061SN/A{ 3432292SN/A for (int i = 0; i < SSITSize; ++i) { 3441061SN/A validSSIT[i] = false; 3451061SN/A } 3461061SN/A 3472292SN/A for (int i = 0; i < LFSTSize; ++i) { 3481061SN/A validLFST[i] = false; 3491061SN/A } 3502292SN/A 3512292SN/A storeList.clear(); 3521061SN/A} 3532348SN/A 3542348SN/Avoid 3552348SN/AStoreSet::dump() 3562348SN/A{ 3572348SN/A cprintf("storeList.size(): %i\n", storeList.size()); 3582348SN/A SeqNumMapIt store_list_it = storeList.begin(); 3592348SN/A 3602348SN/A int num = 0; 3612348SN/A 3622348SN/A while (store_list_it != storeList.end()) { 3632348SN/A cprintf("%i: [sn:%lli] SSID:%i\n", 3642348SN/A num, (*store_list_it).first, (*store_list_it).second); 3652348SN/A num++; 3662348SN/A store_list_it++; 3672348SN/A } 3682348SN/A} 369