src/Sim/Predictor/DepPred/MemDepPred/PerfectMemDepPred.cpp

説明を見る。
00001 // 
00002 // Copyright (c) 2005-2008 Kenichi Watanabe.
00003 // Copyright (c) 2005-2008 Yasuhiro Watari.
00004 // Copyright (c) 2005-2008 Hironori Ichibayashi.
00005 // Copyright (c) 2008-2009 Kazuo Horio.
00006 // Copyright (c) 2009-2013 Naruki Kurata.
00007 // Copyright (c) 2005-2013 Ryota Shioya.
00008 // Copyright (c) 2005-2013 Masahiro Goshima.
00009 // 
00010 // This software is provided 'as-is', without any express or implied
00011 // warranty. In no event will the authors be held liable for any damages
00012 // arising from the use of this software.
00013 // 
00014 // Permission is granted to anyone to use this software for any purpose,
00015 // including commercial applications, and to alter it and redistribute it
00016 // freely, subject to the following restrictions:
00017 // 
00018 // 1. The origin of this software must not be misrepresented; you must not
00019 // claim that you wrote the original software. If you use this software
00020 // in a product, an acknowledgment in the product documentation would be
00021 // appreciated but is not required.
00022 // 
00023 // 2. Altered source versions must be plainly marked as such, and must not be
00024 // misrepresented as being the original software.
00025 // 
00026 // 3. This notice may not be removed or altered from any source
00027 // distribution.
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     // Do not call "Initialize()" of a proxy target object,
00059     // because the "Initialize()" is called by the resource system.
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         // Set endian information to the memory operation object.
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         // Not loads/stores ops do not have memory dependencies.
00087         return;
00088     }
00089 
00090     if( m_fwdEmulator->IsInMissPredictedPath( op ) ){
00091         if( opClass.IsLoad() ){
00092             // If an op is in a mis-predicted path,
00093             // a dummy dependency that is never satisfied is set.
00094             MemDependencyPtr tmpMem(
00095                 m_memDepPool.construct( op->GetCore()->GetNumScheduler() ) 
00096             );
00097             tmpMem->Clear();
00098             op->SetSrcMem( 0, tmpMem );
00099         }
00100         // It is no problem that sores are executed.
00101         return;
00102     }
00103     
00104 
00105     // Check memory addresses executed in a forward emulator, and
00106     // set a dependency to an actually dependent op.
00107 
00108     const MemAccess* consumer = m_fwdEmulator->GetMemoryAccessResult( op );
00109     //if( !consumer )   return;
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     // Search a dependent store from 'op'.
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         //if( !producer ) return;
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             // A store is dependent to a store with the same aligned address,
00131             // because the predictor cannot determine which store is a producer
00132             // of a load when partial read occurs.
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     // Allocate and assign a memory dependency.
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     // Do nothing.
00168 }
00169 
00170 void PerfectMemDepPred::Flush( OpIterator op )
00171 {
00172     // Do nothing.
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 }

Onikiri2に対してTue Jun 18 14:34:25 2013に生成されました。  doxygen 1.4.7