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/PerfectMemDepPred.h"
00035 #include "Sim/Op/Op.h"
00036 #include "Sim/System/ForwardEmulator.h"
00037 #include "Sim/InorderList/InorderList.h"
00038 #include "Sim/Core/Core.h"
00039
00040 using namespace Onikiri;
00041
00042
00043
00044 PerfectMemDepPred::PerfectMemDepPred() :
00045 m_fwdEmulator( NULL ),
00046 m_inorderList( NULL )
00047 {
00048
00049 }
00050
00051 PerfectMemDepPred::~PerfectMemDepPred()
00052 {
00053 ReleaseParam();
00054 }
00055
00056 void PerfectMemDepPred::Initialize( InitPhase phase )
00057 {
00058
00059
00060
00061 if( phase == INIT_PRE_CONNECTION ){
00062 LoadParam();
00063 }
00064 else if( phase == INIT_POST_CONNECTION ){
00065 CheckNodeInitialized( "forwardEmulator", m_fwdEmulator );
00066 CheckNodeInitialized( "inorderList", m_inorderList );
00067
00068
00069 ISAInfoIF* isa = m_fwdEmulator->GetEmulator()->GetISAInfo();
00070 m_memOperations.SetTargetEndian( isa->IsLittleEndian() );
00071 m_memOperations.SetAlignment( isa->GetMaxMemoryAccessByteSize() );
00072
00073 if( !m_fwdEmulator->IsEnabled() ){
00074 THROW_RUNTIME_ERROR(
00075 "A perfect memory dependency predictor requires that a forawrd emulator is enabled."
00076 );
00077 }
00078 }
00079 }
00080
00081 void PerfectMemDepPred::Resolve( OpIterator op )
00082 {
00083 const OpClass& opClass = op->GetOpClass();
00084
00085 if( !opClass.IsMem() ){
00086
00087 return;
00088 }
00089
00090 if( m_fwdEmulator->IsInMissPredictedPath( op ) ){
00091 if( opClass.IsLoad() ){
00092
00093
00094 MemDependencyPtr tmpMem(
00095 m_memDepPool.construct( op->GetCore()->GetNumScheduler() )
00096 );
00097 tmpMem->Clear();
00098 op->SetSrcMem( 0, tmpMem );
00099 }
00100
00101 return;
00102 }
00103
00104
00105
00106
00107
00108 const MemAccess* consumer = m_fwdEmulator->GetMemoryAccessResult( op );
00109
00110 ASSERT( consumer != NULL, "Could not get a pre-executed memory access result. %s", op->ToString(6).c_str() );
00111
00112 bool consumerIsStore = opClass.IsStore();
00113
00114 OpIterator i = m_inorderList->GetPrevIndexOp( op );
00115
00116
00117 while( !i.IsNull() ){
00118
00119 if( !i->GetOpClass().IsStore() ){
00120 i = m_inorderList->GetPrevIndexOp( i );
00121 continue;
00122 }
00123
00124 const MemAccess* producer = m_fwdEmulator->GetMemoryAccessResult( i );
00125
00126 ASSERT( producer != NULL, "Could not get a pre-executed memory access result. %s", op->ToString(6).c_str() );
00127
00128
00129 if( consumerIsStore ){
00130
00131
00132
00133 if( m_memOperations.IsOverlappedInAligned( *consumer, *producer ) ){
00134 op->SetSrcMem( 0, i->GetDstMem(0) );
00135 break;
00136 }
00137 }
00138 else{
00139 if( m_memOperations.IsOverlapped( *consumer, *producer ) ){
00140 op->SetSrcMem( 0, i->GetDstMem(0) );
00141 break;
00142 }
00143 }
00144
00145 i = m_inorderList->GetPrevIndexOp( i );
00146 }
00147 }
00148
00149 void PerfectMemDepPred::Allocate( OpIterator op )
00150 {
00151 if( !op->GetOpClass().IsMem() ) {
00152 return;
00153 }
00154
00155
00156 if( op->GetDstMem(0) == NULL ) {
00157 MemDependencyPtr tmpMem(
00158 m_memDepPool.construct( op->GetCore()->GetNumScheduler() )
00159 );
00160 tmpMem->Clear();
00161 op->SetDstMem( 0, tmpMem );
00162 }
00163 }
00164
00165 void PerfectMemDepPred::Commit( OpIterator op )
00166 {
00167
00168 }
00169
00170 void PerfectMemDepPred::Flush( OpIterator op )
00171 {
00172
00173 }
00174
00175 void PerfectMemDepPred::OrderConflicted( OpIterator producer, OpIterator consumer )
00176 {
00177 ASSERT(
00178 false,
00179 "A perfect memory dependency predictor must not predict incorrect dependencies. \n\n"
00180 "Conflicted producer:\n %s\n\nConflicted consumer:\n%s\n",
00181 producer->ToString(6).c_str(),
00182 consumer->ToString(6).c_str()
00183 );
00184 }
00185
00186 bool PerfectMemDepPred::CanAllocate( OpIterator* infoArray, int numOp )
00187 {
00188 return true;
00189 }