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/BPred/BPred.h"
00035
00036 #include "Utility/RuntimeError.h"
00037 #include "Interface/OpClass.h"
00038 #include "Sim/Dumper/Dumper.h"
00039 #include "Sim/ISAInfo.h"
00040 #include "Sim/Foundation/SimPC.h"
00041 #include "Sim/Core/Core.h"
00042 #include "Sim/Op/Op.h"
00043
00044 #include "Sim/Foundation/Hook/Hook.h"
00045 #include "Sim/Foundation/Hook/HookUtil.h"
00046
00047 #include "Sim/Predictor/BPred/PHT.h"
00048 #include "Sim/Predictor/BPred/DirPredIF.h"
00049 #include "Sim/Predictor/BPred/GlobalHistory.h"
00050 #include "Sim/Predictor/BPred/RAS.h"
00051 #include "Sim/Recoverer/Recoverer.h"
00052 #include "Sim/InorderList/InorderList.h"
00053 #include "Sim/Thread/Thread.h"
00054 #include "Sim/System/ForwardEmulator.h"
00055
00056 namespace Onikiri
00057 {
00058 HookPoint<BPred> BPred::s_branchPredictionMissHook;
00059 };
00060
00061
00062 using namespace Onikiri;
00063 using namespace std;
00064
00065
00066 BPred::Statistics::Statistics()
00067 {
00068 numHit = 0;
00069 numMiss = 0;
00070 }
00071
00072 void BPred::Statistics::SetName( const String& name )
00073 {
00074 this->name = name;
00075 }
00076
00077
00078 BPred::BPred()
00079 {
00080 m_dirPred = 0;
00081 m_btb = 0;
00082 m_core = 0;
00083 m_fwdEmulator = 0;
00084 m_mode = SM_SIMULATION;
00085 m_perfect = false;
00086
00087 BranchTypeUtility util;
00088 m_statistics.resize( util.GetTypeCount() );
00089 for( size_t i = 0; i < util.GetTypeCount(); i++){
00090 m_statistics[i].SetName( util.GetTypeName(i) );
00091 }
00092 m_totalStatistics.SetName( "All" );
00093 }
00094
00095 BPred::~BPred()
00096 {
00097 ReleaseParam();
00098 }
00099
00100
00101 void BPred::Initialize( InitPhase phase )
00102 {
00103 if( phase == INIT_PRE_CONNECTION ){
00104 LoadParam();
00105 }
00106 else if( phase == INIT_POST_CONNECTION ){
00107
00108
00109 CheckNodeInitialized( "dirPred", m_dirPred );
00110 CheckNodeInitialized( "btb", m_btb );
00111 CheckNodeInitialized( "ras", m_ras );
00112 CheckNodeInitialized( "core", m_core );
00113 CheckNodeInitialized( "forwardEmulator", m_fwdEmulator );
00114
00115 if( !m_fwdEmulator->IsEnabled() ){
00116 THROW_RUNTIME_ERROR(
00117 "A perfect memory dependency predictor requires that a forawrd emulator is enabled."
00118 );
00119 }
00120
00121 m_btbPredTable.Resize( *m_core->GetOpArray() );
00122 }
00123 }
00124
00125
00126
00127
00128 PC BPred::Predict( OpIterator op, PC predIndexPC )
00129 {
00130 if( m_perfect && m_mode == SM_SIMULATION ){
00131
00132 const OpStateIF* result = m_fwdEmulator->GetExecutionResult( op );
00133 if( !result ){
00134 THROW_RUNTIME_ERROR( "Pre-executed result cannot be retrieved from a forward emulator." );
00135 }
00136 return
00137 result->GetTaken() ? result->GetTakenPC() : NextPC( result->GetPC() );
00138 }
00139
00140
00141 SimPC pc = op->GetPC();
00142 BTBPredict btbPred = m_btb->Predict(predIndexPC);
00143 bool btbHit = btbPred.hit;
00144
00145 m_btbPredTable[op] = btbPred;
00146
00147
00148 if(!btbHit)
00149 return pc.Next();
00150
00151
00152 PC branchTarget = btbPred.target;
00153
00154
00155 bool predTaken = btbPred.dirPredict ? m_dirPred->Predict(op, predIndexPC) : true;
00156
00157 switch(btbPred.type){
00158 case BT_NON:
00159 ASSERT(0, "BT_NON is invalid.");
00160 return pc.Next();
00161
00162 case BT_CONDITIONAL:
00163
00164
00165 return predTaken ? branchTarget : pc.Next();
00166
00167 case BT_UNCONDITIONAL:
00168
00169 return branchTarget;
00170
00171 case BT_CALL:
00172
00173
00174 m_ras[op->GetLocalTID()]->Push(pc);
00175 return branchTarget;
00176
00177 case BT_RETURN:
00178
00179 return m_ras[op->GetLocalTID()]->Pop();
00180
00181 case BT_CONDITIONAL_RETURN:
00182
00183
00184 return predTaken ? m_ras[op->GetLocalTID()]->Pop() : pc.Next();
00185
00186 case BT_END:
00187 break;
00188 }
00189
00190
00191 THROW_RUNTIME_ERROR("reached end of Bpred::Predict\n");
00192
00193 return pc.Next();
00194 }
00195
00196
00197 void BPred::Finished( OpIterator op )
00198 {
00199 if( m_perfect ){
00200 return;
00201 }
00202
00203 const OpClass& opClass = op->GetOpClass();
00204
00205
00206 if( !opClass.IsBranch() ) {
00207 return;
00208 }
00209
00210
00211 RecoveryFromBPredMiss( op );
00212
00213
00214
00215 if( opClass.IsConditionalBranch() && m_btbPredTable[op].hit ){
00216 m_dirPred->Finished( op );
00217 }
00218 }
00219
00220
00221 void BPred::Commit( OpIterator op )
00222 {
00223 if( m_perfect && m_mode != SM_SIMULATION ){
00224 return;
00225 }
00226
00227 const OpClass& opClass = op->GetOpClass();
00228 if( !opClass.IsBranch() )
00229 return;
00230
00231 bool conditional = opClass.IsConditionalBranch();
00232
00233 if( !m_perfect ){
00234
00235 const BTBPredict& predict = m_btbPredTable[op];
00236 m_btb->Update( op, predict );
00237
00238
00239
00240 if( conditional && predict.hit ){
00241 m_dirPred->Retired( op );
00242 }
00243 }
00244
00245
00246 PC pcTaken = op->GetTakenPC();
00247 PC pcPred = op->GetPredPC();
00248 PC pcNext = NextPC( op->GetPC() );
00249 bool taken = conditional ? op->GetTaken() : true;
00250 PC pcResult = taken ? pcTaken : pcNext;
00251
00252 BranchTypeUtility util;
00253 BranchType type = util.OpClassToBranchType( opClass );
00254 if( pcPred == pcResult ){
00255 m_statistics[type].numHit++;
00256 m_totalStatistics.numHit++;
00257 }
00258 else{
00259 m_statistics[type].numMiss++;
00260 m_totalStatistics.numMiss++;
00261 }
00262
00263 }
00264
00265
00266 void BPred::RecoveryFromBPredMiss( OpIterator branch )
00267 {
00268
00269 if( m_mode != PhysicalResourceNode::SM_SIMULATION ){
00270 return;
00271 }
00272
00273
00274
00275 if( IsPerfect() ){
00276 return;
00277 }
00278
00279 if( branch->GetPredPC() != branch->GetNextPC() ) {
00280
00281 g_dumper.Dump( DS_BRANCH_PREDICTION_MISS, branch );
00282 HOOK_SECTION_OP( s_branchPredictionMissHook, branch )
00283 {
00284 Recoverer* recoverer = branch->GetThread()->GetRecoverer();
00285 recoverer->RecoverBPredMiss( branch );
00286 }
00287 }
00288 }