00001 package edu.rice.cs.hpc.data.experiment.scope.visitors;
00002
00003 import java.util.*;
00004
00005 import edu.rice.cs.hpc.data.experiment.Experiment;
00006 import edu.rice.cs.hpc.data.experiment.scope.AlienScope;
00007 import edu.rice.cs.hpc.data.experiment.scope.CallSiteScope;
00008 import edu.rice.cs.hpc.data.experiment.scope.FileScope;
00009 import edu.rice.cs.hpc.data.experiment.scope.GroupScope;
00010 import edu.rice.cs.hpc.data.experiment.scope.LineScope;
00011 import edu.rice.cs.hpc.data.experiment.scope.LoadModuleScope;
00012 import edu.rice.cs.hpc.data.experiment.scope.LoopScope;
00013 import edu.rice.cs.hpc.data.experiment.scope.ProcedureScope;
00014 import edu.rice.cs.hpc.data.experiment.scope.RootScope;
00015 import edu.rice.cs.hpc.data.experiment.scope.Scope;
00016 import edu.rice.cs.hpc.data.experiment.scope.ScopeVisitType;
00017 import edu.rice.cs.hpc.data.experiment.scope.StatementRangeScope;
00018 import edu.rice.cs.hpc.data.experiment.scope.filters.ExclusiveOnlyMetricPropagationFilter;
00019 import edu.rice.cs.hpc.data.experiment.scope.filters.InclusiveOnlyMetricPropagationFilter;
00020 import edu.rice.cs.hpc.data.experiment.source.SourceFile;
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 public class FlatViewScopeVisitor implements IScopeVisitor {
00032 private Hashtable<Integer, LoadModuleScope> htFlatLoadModuleScope;
00033 private Hashtable<String, FileScope> htFlatFileScope;
00034 private HashMap<String, FlatScopeInfo> htFlatScope;
00035 private HashMap<String, Scope[]> htFlatCostAdded;
00036
00037 private Experiment experiment;
00038 private RootScope root_ft;
00039
00040 private InclusiveOnlyMetricPropagationFilter inclusive_filter;
00041 private ExclusiveOnlyMetricPropagationFilter exclusive_filter;
00042
00043
00044
00045
00046
00047
00048
00049
00050 public FlatViewScopeVisitor( Experiment exp, RootScope root) {
00051 this.experiment = exp;
00052
00053 this.htFlatLoadModuleScope = new Hashtable<Integer, LoadModuleScope>();
00054 this.htFlatFileScope = new Hashtable<String, FileScope>();
00055 this.htFlatScope = new HashMap<String, FlatScopeInfo>();
00056 this.htFlatCostAdded = new HashMap<String, Scope[]>();
00057
00058 this.root_ft = root;
00059
00060 this.inclusive_filter = new InclusiveOnlyMetricPropagationFilter( exp );
00061 this.exclusive_filter = new ExclusiveOnlyMetricPropagationFilter( exp );
00062 }
00063
00064
00065 public void visit(Scope scope, ScopeVisitType vt) { }
00066 public void visit(RootScope scope, ScopeVisitType vt) { }
00067 public void visit(LoadModuleScope scope, ScopeVisitType vt) { }
00068 public void visit(FileScope scope, ScopeVisitType vt) { }
00069 public void visit(AlienScope scope, ScopeVisitType vt) { }
00070 public void visit(StatementRangeScope scope, ScopeVisitType vt) { }
00071 public void visit(GroupScope scope, ScopeVisitType vt) { }
00072
00073 public void visit(CallSiteScope scope, ScopeVisitType vt) {
00074 add(scope,vt, true, false);
00075 }
00076 public void visit(LineScope scope, ScopeVisitType vt) {
00077 add(scope,vt, true, true);
00078 }
00079 public void visit(LoopScope scope, ScopeVisitType vt) {
00080 add(scope,vt, true, false);
00081 }
00082 public void visit(ProcedureScope scope, ScopeVisitType vt) {
00083 add(scope,vt, true, false);
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 private void add( Scope scope, ScopeVisitType vt, boolean add_inclusive, boolean add_exclusive ) {
00095
00096 String id = this.getID(scope);
00097
00098 if (vt == ScopeVisitType.PreVisit ) {
00099
00100
00101
00102 Scope flat_info[] = this.htFlatCostAdded.get( id );
00103 if (flat_info != null) {
00104 this.htFlatCostAdded.remove(id);
00105 }
00106
00107 FlatScopeInfo objFlat = this.getFlatCounterPart(scope, scope, id);
00108
00109
00110
00111
00112
00113 addCostIfNecessary(id, objFlat.flat_lm, scope, add_inclusive, add_exclusive);
00114 addCostIfNecessary(id, objFlat.flat_file, scope, add_inclusive, add_exclusive);
00115
00116
00117
00118
00119 if (scope instanceof CallSiteScope) {
00120 ProcedureScope proc_cct_s = ((CallSiteScope) scope).getProcedureScope();
00121 this.getFlatCounterPart(proc_cct_s, scope, id);
00122 }
00123
00124 } else {
00125
00126
00127
00128
00129 Scope flat_info[] = this.htFlatCostAdded.get( id );
00130 if (flat_info != null)
00131 for (int i=0; i<flat_info.length; i++) {
00132 this.decrementCounter(flat_info[i]);
00133 }
00134 }
00135 }
00136
00137
00138
00139
00140
00141
00142 private void decrementCounter(Scope flat_s) {
00143 if (flat_s != null) {
00144 flat_s.decrementCounter();
00145 }
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 private FlatScopeInfo getFlatScope( Scope cct_s ) {
00159
00160
00161
00162 String id = this.getID(cct_s);
00163
00164 FlatScopeInfo flat_info_s = this.htFlatScope.get( id );
00165
00166 if (flat_info_s == null) {
00167
00168
00169
00170
00171 flat_info_s = new FlatScopeInfo();
00172
00173
00174
00175
00176
00177
00178 ProcedureScope proc_cct_s;
00179 if (cct_s instanceof CallSiteScope) {
00180 proc_cct_s = ((CallSiteScope)cct_s).getProcedureScope();
00181 } else {
00182 proc_cct_s = findEnclosingProcedure(cct_s);
00183 }
00184
00185 if (proc_cct_s == null) {
00186 throw new RuntimeException("Cannot find the enclosing procedure for " + cct_s);
00187 }
00188
00189
00190
00191
00192 flat_info_s.flat_s = cct_s.duplicate();
00193
00194
00195
00196
00197 flat_info_s.flat_lm = this.createFlatModuleScope(proc_cct_s);
00198
00199
00200
00201
00202 flat_info_s.flat_file = this.createFlatFileScope(proc_cct_s, flat_info_s.flat_lm);
00203
00204
00205
00206
00207 if (flat_info_s.flat_s instanceof ProcedureScope) {
00208 this.addToTree(flat_info_s.flat_file, flat_info_s.flat_s);
00209 }
00210
00211
00212
00213
00214 this.htFlatScope.put( id, flat_info_s);
00215 }
00216
00217 return flat_info_s;
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227 private LoadModuleScope createFlatModuleScope(ProcedureScope proc_cct_s) {
00228 LoadModuleScope lm = proc_cct_s.getLoadModule();
00229 LoadModuleScope lm_flat_s = null;
00230
00231
00232 if (lm != null) {
00233 lm_flat_s = this.htFlatLoadModuleScope.get(lm.hashCode());
00234 if (lm_flat_s == null) {
00235
00236 lm_flat_s = (LoadModuleScope) lm.duplicate();
00237
00238 this.addToTree(root_ft, lm_flat_s);
00239
00240 this.htFlatLoadModuleScope.put(lm.hashCode(), lm_flat_s);
00241 }
00242 }
00243 return lm_flat_s;
00244 }
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 private String getUniqueFileID(SourceFile file, LoadModuleScope lm)
00256 {
00257 return lm.getFlatIndex() + "/" + file.getFileID();
00258 }
00259
00260
00261
00262
00263
00264
00265
00266 private FileScope createFlatFileScope(Scope cct_s, LoadModuleScope flat_lm) {
00267 SourceFile src_file = cct_s.getSourceFile();
00268 String unique_file_id = getUniqueFileID(src_file, flat_lm);
00269 FileScope flat_file = this.htFlatFileScope.get( unique_file_id );
00270
00271
00272
00273
00274 if ( (flat_file == null) ){
00275 flat_file = createFileScope(src_file, flat_lm, unique_file_id);
00276
00277 } else {
00278
00279 Scope parent_lm = flat_file.getParentScope();
00280 if (parent_lm instanceof LoadModuleScope) {
00281 LoadModuleScope flat_parent_lm = (LoadModuleScope) parent_lm;
00282
00283
00284 if (flat_parent_lm.hashCode() != flat_lm.hashCode() ) {
00285
00286 flat_file = createFileScope(src_file, flat_lm, unique_file_id);
00287 }
00288 }
00289
00290 }
00291 return flat_file;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301 private FileScope createFileScope(SourceFile src_file, LoadModuleScope lm_s, String unique_file_id) {
00302 int fileID = src_file.getFileID();
00303 FileScope file_s = new FileScope( this.experiment, src_file, fileID );
00304
00305
00306
00307 if (lm_s == null)
00308 this.addToTree(root_ft, file_s);
00309 else
00310 this.addToTree(lm_s, file_s);
00311 this.htFlatFileScope.put( unique_file_id, file_s);
00312
00313 return file_s;
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323 private FlatScopeInfo getFlatCounterPart( Scope cct_s, Scope cct_s_metrics, String id) {
00324
00325
00326
00327 Scope cct_parent_s = cct_s.getParentScope() ;
00328 Scope flat_enc_s = null;
00329
00330 if (cct_parent_s != null) {
00331 if (cct_parent_s instanceof RootScope) {
00332
00333
00334
00335 flat_enc_s = null;
00336 } else {
00337 if ( cct_parent_s instanceof CallSiteScope ) {
00338
00339
00340
00341 ProcedureScope proc_cct_s = ((CallSiteScope)cct_parent_s).getProcedureScope();
00342 FlatScopeInfo flat_enc_info = this.getFlatScope(proc_cct_s);
00343 flat_enc_s = flat_enc_info.flat_s;
00344
00345 } else {
00346
00347
00348
00349 FlatScopeInfo flat_enc_info = this.getFlatScope(cct_parent_s);
00350 flat_enc_s = flat_enc_info.flat_s;
00351 }
00352
00353 }
00354 }
00355
00356 FlatScopeInfo objFlat = this.getFlatScope(cct_s);
00357
00358 if (flat_enc_s != null)
00359 this.addToTree(flat_enc_s, objFlat.flat_s);
00360
00361 this.addCostIfNecessary(id, objFlat.flat_s, cct_s_metrics, true, true);
00362 return objFlat;
00363
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 private String getID( Scope scope ) {
00375 int id = scope.hashCode();
00376 String hash_id = scope.getClass().getSimpleName();
00377 if (hash_id != null) {
00378 hash_id = hash_id.substring(0, 2) + id;
00379 } else {
00380 hash_id = String.valueOf(id);
00381 }
00382 return hash_id;
00383 }
00384
00385
00386
00387
00388
00389
00390
00391 private void addToTree( Scope parent, Scope child ) {
00392 int nkids = parent.getSubscopeCount();
00393
00394
00395
00396
00397
00398 for (int i=0; i<nkids; i++) {
00399 Scope kid = parent.getSubscope(i);
00400 if ( this.isTheSameScope(kid, child) )
00401 return;
00402 }
00403 this.addChild(parent, child);
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413 private boolean isTheSameScope(Scope s1, Scope s2) {
00414
00415
00416 if ( s1.getClass() != s2.getClass() )
00417 return false;
00418
00419 return (s1.hashCode() == s2.hashCode());
00420 }
00421
00422
00423
00424
00425
00426
00427
00428 private void addChild(Scope parent, Scope child) {
00429 if (parent.hashCode() == child.hashCode())
00430 System.err.println("ERROR: Same ID "+parent.hashCode()+": "+parent + " - " + child);
00431 parent.addSubscope(child);
00432 child.setParentScope(parent);
00433 }
00434
00435
00436
00437
00438
00439
00440
00441 private ProcedureScope findEnclosingProcedure(Scope cct_s)
00442 {
00443 if (cct_s instanceof ProcedureScope)
00444 return (ProcedureScope) cct_s;
00445 Scope parent = cct_s.getParentScope();
00446 while(parent != null) {
00447 if (parent instanceof CallSiteScope) {
00448 ProcedureScope proc = ((CallSiteScope) parent).getProcedureScope();
00449 if (!proc.isAlien()) return proc;
00450 }
00451 if (parent instanceof ProcedureScope) {
00452 ProcedureScope proc = (ProcedureScope) parent;
00453 if (!proc.isAlien()) return proc;
00454 }
00455 if (parent instanceof RootScope) return null;
00456 parent = parent.getParentScope();
00457 }
00458 return null;
00459 }
00460
00461
00462
00463
00464
00465
00466
00467 private boolean isOutermostInstance(Scope scope) {
00468 return scope.getCounter() == 1;
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478 private void addCostIfNecessary( String objCode, Scope flat_s, Scope cct_s, boolean add_inclusive, boolean add_exclusive ) {
00479 if (flat_s == null)
00480 return;
00481
00482 flat_s.incrementCounter();
00483
00484 if (isOutermostInstance(flat_s)) {
00485 if (add_inclusive)
00486 flat_s.combine(cct_s, inclusive_filter);
00487 }
00488 if (add_exclusive)
00489 flat_s.combine(cct_s, exclusive_filter);
00490
00491
00492
00493
00494 Scope arr_new_scopes[];
00495 Scope scope_added[] = htFlatCostAdded.get( objCode );
00496 if (scope_added != null) {
00497 int nb_scopes = scope_added.length;
00498 arr_new_scopes = new Scope[nb_scopes+1];
00499 System.arraycopy(scope_added, 0, arr_new_scopes, 0, nb_scopes);
00500 arr_new_scopes[nb_scopes] = flat_s;
00501 } else {
00502 arr_new_scopes = new Scope[1];
00503 arr_new_scopes[0] = flat_s;
00504 }
00505 htFlatCostAdded.put(objCode, arr_new_scopes);
00506
00507 }
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 private class FlatScopeInfo {
00519 LoadModuleScope flat_lm;
00520 FileScope flat_file;
00521 Scope flat_s;
00522 }
00523 }