00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <pch.h>
00033
00034 #include "Sim/Predictor/DepPred/MemDepPred/StoreSet.h"
00035 #include "Sim/Op/Op.h"
00036
00037 using namespace Onikiri;
00038 using namespace boost;
00039
00040 StoreSet::StoreSet() :
00041 m_core(0),
00042 m_storeIDTable (0),
00043 m_producerTable (0),
00044 m_numStoreIDTableEntryBits (0),
00045 m_numStoreIDTableWays (0),
00046 m_numProducerTableEntryBits (0),
00047 m_numProducerTableWays (0),
00048 m_numStoreIDTableEntries (0),
00049 m_numProducerTableEntries (0),
00050 m_numAccessOrderViolated (0)
00051 {
00052 }
00053
00054 StoreSet::~StoreSet()
00055 {
00056 if( m_storeIDTable ) {
00057 delete m_storeIDTable;
00058 }
00059 if( m_producerTable ) {
00060 delete m_producerTable;
00061 }
00062
00063
00064 m_numStoreIDTableEntries = (1 << m_numStoreIDTableEntryBits);
00065 m_numProducerTableEntries = (1 << m_numProducerTableEntryBits);
00066 ReleaseParam();
00067 }
00068
00069 void StoreSet::Initialize(InitPhase phase)
00070 {
00071 if( phase == INIT_PRE_CONNECTION ) {
00072 LoadParam();
00073 } else if( phase == INIT_POST_CONNECTION ) {
00074 m_storeIDTable =
00075 new StoreIDTableType(
00076 HasherType( m_numStoreIDTableEntryBits, WORD_BITS ),
00077 m_numStoreIDTableWays
00078 );
00079 m_producerTable =
00080 new ProducerTableType(
00081 HasherType( m_numProducerTableEntryBits, WORD_BITS ),
00082 m_numProducerTableWays
00083 );
00084 m_allocatedStoreIDTable.Resize(*m_core->GetOpArray());
00085 }
00086
00087 }
00088
00089 void StoreSet::Resolve(OpIterator op)
00090 {
00091 if( !op->GetOpClass().IsMem() ) {
00092 return;
00093 }
00094
00095 StoreSetID storeSetID = GetStoreSetID(op);
00096 if( storeSetID.address != INVALID_STORESET_ID) {
00097 OpIterator producer = GetProducerStore(storeSetID);
00098 if( !producer.IsNull() ) {
00099 ResolveMemDependency(op, producer);
00100 }
00101 }
00102 }
00103
00104
00105 void StoreSet::Allocate(OpIterator op)
00106 {
00107
00108 if( !op->GetOpClass().IsStore() ) {
00109 return;
00110 }
00111
00112 StoreSetID storeSetID = GetStoreSetID(op);
00113 if( storeSetID.address != INVALID_STORESET_ID) {
00114
00115 UpdateProducerTable(storeSetID, op);
00116 AllocateMemDependency(op);
00117 }
00118 }
00119
00120 void StoreSet::Commit(OpIterator op)
00121 {
00122 if( op->GetOpClass().IsMem() ) {
00123 Deallocate(op);
00124 }
00125 }
00126
00127 void StoreSet::Flush(OpIterator op)
00128 {
00129 if( op->GetStatus() == OpStatus::OS_FETCH ){
00130 return;
00131 }
00132 if( op->GetOpClass().IsMem() ) {
00133 Deallocate(op);
00134 }
00135 }
00136
00137
00138 void StoreSet::OrderConflicted(OpIterator producer, OpIterator consumer)
00139 {
00140 ASSERT(producer->GetOpClass().IsStore(), "producerOp is not store(%s)", producer->ToString(6).c_str());
00141 ASSERT(consumer->GetOpClass().IsMem(), "consumerOp is not load/store(%s)", consumer->ToString(6).c_str());
00142
00143 m_numAccessOrderViolated++;
00144
00145 StoreSetID producerID = GetStoreSetID(producer);
00146 StoreSetID consumerID = GetStoreSetID(consumer);
00147
00148
00149 if( producerID.address == INVALID_STORESET_ID && consumerID.address == INVALID_STORESET_ID ) {
00150
00151 StoreSetID id = GetNewID(producer);
00152 UpdateStoreSetIDTable(producer, id);
00153 UpdateStoreSetIDTable(consumer, id);
00154 } else if( producerID.address != INVALID_STORESET_ID && consumerID.address == INVALID_STORESET_ID ) {
00155
00156 UpdateStoreSetIDTable(consumer, producerID);
00157 } else if( producerID.address == INVALID_STORESET_ID && consumerID.address != INVALID_STORESET_ID ) {
00158
00159 UpdateStoreSetIDTable(producer, consumerID);
00160 } else {
00161 if( producerID == consumerID ) {
00162
00163 return;
00164 }
00165
00166
00167 if( producerID.address < consumerID.address ) {
00168 UpdateStoreSetIDTable(consumer, producerID);
00169 } else {
00170
00171 ReleaseProducerTable(producer);
00172 UpdateStoreSetIDTable(producer, consumerID);
00173 }
00174 }
00175 }
00176
00177 bool StoreSet::CanAllocate(OpIterator* infoArray, int numOp)
00178 {
00179 return true;
00180 }
00181
00182 void StoreSet::AllocateMemDependency(OpIterator op)
00183 {
00184 if( op->GetDstMem(0) == NULL ) {
00185 MemDependencyPtr tmpMem(
00186 m_memDepPool.construct(m_core->GetNumScheduler()) );
00187 tmpMem->Clear();
00188 op->SetDstMem(0, tmpMem);
00189 }
00190 }
00191
00192 void StoreSet::ResolveMemDependency(OpIterator consumer, OpIterator producer)
00193 {
00194 ASSERT(producer->GetOpClass().IsStore(), "op is not store(%s)", producer->ToString(6).c_str());
00195 consumer->SetSrcMem(0, producer->GetDstMem(0));
00196 }
00197
00198 void StoreSet::Deallocate(const OpIterator op)
00199 {
00200 StoreSetID id = GetStoreSetID(op);
00201 if( id.address ) {
00202 ReleaseProducerTable(op);
00203 m_allocatedStoreIDTable[op] = StoreSetID();
00204 }
00205 }
00206
00207
00208 void StoreSet::UpdateStoreSetIDTable(OpIterator op, StoreSetID id)
00209 {
00210 m_storeIDTable->write( op->GetPC(), id );
00211 }
00212
00213
00214 void StoreSet::UpdateProducerTable(StoreSetID id, OpIterator op)
00215 {
00216 m_producerTable->write(id, op);
00217 m_allocatedStoreIDTable[op] = id;
00218 }
00219
00220
00221
00222 void StoreSet::ReleaseProducerTable(OpIterator op)
00223 {
00224 StoreSetID allocatedID = m_allocatedStoreIDTable[op];
00225
00226 OpIterator lastProducer;
00227 bool producerFound = m_producerTable->read( allocatedID, &lastProducer ) != m_producerTable->end();
00228 if( producerFound ) {
00229 if( !lastProducer.IsNull() && lastProducer->GetGlobalSerialID() == op->GetGlobalSerialID() ){
00230
00231 m_producerTable->write( allocatedID, OpIterator(0) );
00232 }
00233 }
00234 }
00235
00236
00237 StoreSet::StoreSetID StoreSet::GetNewID(const OpIterator op)
00238 {
00239 StoreSetID id = op->GetPC();
00240 m_producerTable->write( op->GetPC(), OpIterator(0) );
00241 return id;
00242 }
00243
00244 StoreSet::StoreSetID StoreSet::GetStoreSetID(const OpIterator op)
00245 {
00246 StoreSetID id( op->GetPID(), op->GetTID(), INVALID_STORESET_ID );
00247 m_storeIDTable->read( op->GetPC(), &id );
00248 return id;
00249 }
00250
00251 OpIterator StoreSet::GetProducerStore(const StoreSetID id)
00252 {
00253 OpIterator producer;
00254 bool producerFound = m_producerTable->read( id, &producer ) != m_producerTable->end();
00255 if( producerFound && !producer.IsNull()) {
00256 return producer;
00257 } else {
00258 return OpIterator(0);
00259 }
00260 }