changes to handle fixed point analysis properly + bug fix.
[IRC.git] / Robust / src / Analysis / MLP / MLPAnalysis.java
1 package Analysis.MLP;
2
3 import Analysis.CallGraph.*;
4 import Analysis.Liveness;
5 import Analysis.OwnershipAnalysis.*;
6 import IR.*;
7 import IR.Flat.*;
8 import IR.Tree.*;
9 import java.util.*;
10 import java.io.*;
11
12
13 public class MLPAnalysis {
14
15   // data from the compiler
16   private State             state;
17   private TypeUtil          typeUtil;
18   private CallGraph         callGraph;
19   private OwnershipAnalysis ownAnalysis;
20
21
22   // an implicit SESE is automatically spliced into
23   // the IR graph around the C main before this analysis--it
24   // is nothing special except that we can make assumptions
25   // about it, such as the whole program ends when it ends
26   private FlatSESEEnterNode mainSESE;
27
28   // SESEs that are the root of an SESE tree belong to this
29   // set--the main SESE is always a root, statically SESEs
30   // inside methods are a root because we don't know how they
31   // will fit into the runtime tree of SESEs
32   private Set<FlatSESEEnterNode> rootSESEs;
33
34   // simply a set of every reachable SESE in the program, not
35   // including caller placeholder SESEs
36   private Set<FlatSESEEnterNode> allSESEs;
37
38
39   // A mapping of flat nodes to the stack of SESEs for that node, where
40   // an SESE is the child of the SESE directly below it on the stack.
41   // These stacks do not reflect the heirarchy over methods calls--whenever
42   // there is an empty stack it means all variables are available.
43   private Hashtable< FlatNode, Stack<FlatSESEEnterNode> > seseStacks;
44
45   private Hashtable< FlatNode, Set<TempDescriptor>      > livenessRootView;
46   private Hashtable< FlatNode, Set<TempDescriptor>      > livenessVirtualReads;
47   private Hashtable< FlatNode, VarSrcTokTable           > variableResults;
48   private Hashtable< FlatNode, Set<TempDescriptor>      > notAvailableResults;
49   private Hashtable< FlatNode, CodePlan                 > codePlans;
50
51   private Hashtable< FlatEdge, FlatWriteDynamicVarNode  > wdvNodesToSpliceIn;
52   
53   private Hashtable< MethodContext, HashSet<AllocationSite>> mapMethodContextToLiveInAllocationSiteSet;
54   
55   private Hashtable < FlatNode, ParentChildConflictsMap > conflictsResults;
56   private Hashtable< FlatMethod, MethodSummary > methodSummaryResults;
57   
58   // temporal data structures to track analysis progress.
59   private MethodSummary currentMethodSummary;
60   private HashSet<PreEffectsKey> preeffectsSet;
61
62   public static int maxSESEage = -1;
63
64
65   // use these methods in BuildCode to have access to analysis results
66   public FlatSESEEnterNode getMainSESE() {
67     return mainSESE;
68   }
69
70   public Set<FlatSESEEnterNode> getRootSESEs() {
71     return rootSESEs;
72   }
73
74   public Set<FlatSESEEnterNode> getAllSESEs() {
75     return allSESEs;
76   }
77
78   public int getMaxSESEage() {
79     return maxSESEage;
80   }
81
82   // may be null
83   public CodePlan getCodePlan( FlatNode fn ) {
84     CodePlan cp = codePlans.get( fn );
85     return cp;
86   }
87
88
89   public MLPAnalysis( State             state,
90                       TypeUtil          tu,
91                       CallGraph         callGraph,
92                       OwnershipAnalysis ownAnalysis
93                       ) {
94
95     double timeStartAnalysis = (double) System.nanoTime();
96
97     this.state       = state;
98     this.typeUtil    = tu;
99     this.callGraph   = callGraph;
100     this.ownAnalysis = ownAnalysis;
101     this.maxSESEage  = state.MLP_MAXSESEAGE;
102
103     rootSESEs = new HashSet<FlatSESEEnterNode>();
104     allSESEs  = new HashSet<FlatSESEEnterNode>();
105
106     seseStacks           = new Hashtable< FlatNode, Stack<FlatSESEEnterNode> >();    
107     livenessRootView     = new Hashtable< FlatNode, Set<TempDescriptor>      >();
108     livenessVirtualReads = new Hashtable< FlatNode, Set<TempDescriptor>      >();
109     variableResults      = new Hashtable< FlatNode, VarSrcTokTable           >();
110     notAvailableResults  = new Hashtable< FlatNode, Set<TempDescriptor>      >();
111     codePlans            = new Hashtable< FlatNode, CodePlan                 >();
112     wdvNodesToSpliceIn   = new Hashtable< FlatEdge, FlatWriteDynamicVarNode  >();
113     
114     mapMethodContextToLiveInAllocationSiteSet = new Hashtable< MethodContext, HashSet<AllocationSite>>();
115     
116     conflictsResults = new Hashtable < FlatNode, ParentChildConflictsMap >();
117     methodSummaryResults=new Hashtable<FlatMethod, MethodSummary>();
118
119     FlatMethod fmMain = state.getMethodFlat( typeUtil.getMain() );
120
121     mainSESE = (FlatSESEEnterNode) fmMain.getNext(0);    
122     mainSESE.setfmEnclosing( fmMain );
123     mainSESE.setmdEnclosing( fmMain.getMethod() );
124     mainSESE.setcdEnclosing( fmMain.getMethod().getClassDesc() );
125
126
127     // 1st pass
128     // run analysis on each method that is actually called
129     // reachability analysis already computed this so reuse
130     Iterator<Descriptor> methItr = ownAnalysis.descriptorsToAnalyze.iterator();
131     while( methItr.hasNext() ) {
132       Descriptor d  = methItr.next();      
133       FlatMethod fm = state.getMethodFlat( d );
134
135       // find every SESE from methods that may be called
136       // and organize them into roots and children
137       buildForestForward( fm );
138     }
139
140
141     // 2nd pass, results are saved in FlatSESEEnterNode, so
142     // intermediate results, for safety, are discarded
143     Iterator<FlatSESEEnterNode> rootItr = rootSESEs.iterator();
144     while( rootItr.hasNext() ) {
145       FlatSESEEnterNode root = rootItr.next();
146       livenessAnalysisBackward( root, 
147                                 true, 
148                                 null );
149     }
150
151
152     // 3rd pass
153     methItr = ownAnalysis.descriptorsToAnalyze.iterator();
154     while( methItr.hasNext() ) {
155       Descriptor d  = methItr.next();      
156       FlatMethod fm = state.getMethodFlat( d );
157
158       // starting from roots do a forward, fixed-point
159       // variable analysis for refinement and stalls
160       variableAnalysisForward( fm );
161     }
162
163     // 4th pass, compute liveness contribution from
164     // virtual reads discovered in variable pass
165     rootItr = rootSESEs.iterator();
166     while( rootItr.hasNext() ) {
167       FlatSESEEnterNode root = rootItr.next();
168       livenessAnalysisBackward( root, 
169                                 true, 
170                                 null );
171     }
172
173
174     /*
175       SOMETHING IS WRONG WITH THIS, DON'T USE IT UNTIL IT CAN BE FIXED
176
177     // 5th pass
178     methItr = ownAnalysis.descriptorsToAnalyze.iterator();
179     while( methItr.hasNext() ) {
180       Descriptor d  = methItr.next();      
181       FlatMethod fm = state.getMethodFlat( d );
182
183       // prune variable results in one traversal
184       // by removing reference variables that are not live
185       pruneVariableResultsWithLiveness( fm );
186     }
187     */
188
189
190     // 6th pass
191     methItr = ownAnalysis.descriptorsToAnalyze.iterator();
192     while( methItr.hasNext() ) {
193       Descriptor d  = methItr.next();      
194       FlatMethod fm = state.getMethodFlat( d );
195
196       // compute what is not available at every program
197       // point, in a forward fixed-point pass
198       notAvailableForward( fm );
199     }
200     
201     // new pass
202     methItr = ownAnalysis.descriptorsToAnalyze.iterator();
203         JavaCallGraph javaCallGraph = new JavaCallGraph(state,tu);
204     while( methItr.hasNext() ) {
205       Descriptor d  = methItr.next();      
206       FlatMethod fm = state.getMethodFlat( d );
207       methodEffects(fm,javaCallGraph);
208     }
209     
210     // Parent/child memory conflicts analysis
211     seseConflictsForward(javaCallGraph);
212     
213     
214     // disjoint analysis with a set of flagged allocation sites of live-in variable
215         try {
216           OwnershipAnalysis oa2 = new OwnershipAnalysis(state, tu, callGraph, new Liveness(),
217                                 state.OWNERSHIPALLOCDEPTH, false,
218                                 false, state.OWNERSHIPALIASFILE,
219                                 state.METHODEFFECTS,
220                                 mapMethodContextToLiveInAllocationSiteSet);
221                 // debug
222                 methItr = oa2.descriptorsToAnalyze.iterator();
223                 while (methItr.hasNext()) {
224                         Descriptor d = methItr.next();
225                         FlatMethod fm = state.getMethodFlat(d);
226                         debugFunction(oa2, fm);
227                 }
228                 //
229         } catch (IOException e) {
230                 System.err.println(e);
231         }
232     
233
234
235     // 7th pass
236     methItr = ownAnalysis.descriptorsToAnalyze.iterator();
237     while( methItr.hasNext() ) {
238       Descriptor d  = methItr.next();      
239       FlatMethod fm = state.getMethodFlat( d );
240
241       // compute a plan for code injections
242       codePlansForward( fm );
243     }
244
245
246     // splice new IR nodes into graph after all
247     // analysis passes are complete
248     Iterator spliceItr = wdvNodesToSpliceIn.entrySet().iterator();
249     while( spliceItr.hasNext() ) {
250       Map.Entry               me    = (Map.Entry)               spliceItr.next();
251       FlatWriteDynamicVarNode fwdvn = (FlatWriteDynamicVarNode) me.getValue();
252       fwdvn.spliceIntoIR();
253     }
254
255
256     double timeEndAnalysis = (double) System.nanoTime();
257     double dt = (timeEndAnalysis - timeStartAnalysis)/(Math.pow( 10.0, 9.0 ) );
258     String treport = String.format( "The mlp analysis took %.3f sec.", dt );
259     System.out.println( treport );
260
261     if( state.MLPDEBUG ) {      
262       try {
263         writeReports( treport );
264       } catch( IOException e ) {}
265     }
266   }
267
268
269   private void buildForestForward( FlatMethod fm ) {
270     
271     // start from flat method top, visit every node in
272     // method exactly once, find SESEs and remember
273     // roots and child relationships
274     Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
275     flatNodesToVisit.add( fm );
276
277     Set<FlatNode> visited = new HashSet<FlatNode>();    
278
279     Stack<FlatSESEEnterNode> seseStackFirst = new Stack<FlatSESEEnterNode>();
280     seseStacks.put( fm, seseStackFirst );
281
282     while( !flatNodesToVisit.isEmpty() ) {
283       Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
284       FlatNode fn = fnItr.next();
285
286       Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
287       assert seseStack != null;      
288
289       flatNodesToVisit.remove( fn );
290       visited.add( fn );      
291
292       buildForest_nodeActions( fn, seseStack, fm );
293
294       for( int i = 0; i < fn.numNext(); i++ ) {
295         FlatNode nn = fn.getNext( i );
296
297         if( !visited.contains( nn ) ) {
298           flatNodesToVisit.add( nn );
299
300           // clone stack and send along each analysis path
301           seseStacks.put( nn, (Stack<FlatSESEEnterNode>)seseStack.clone() );
302         }
303       }
304     }      
305   }
306
307   private void buildForest_nodeActions( FlatNode fn,                                                       
308                                         Stack<FlatSESEEnterNode> seseStack,
309                                         FlatMethod fm ) {
310     switch( fn.kind() ) {
311
312     case FKind.FlatSESEEnterNode: {
313       FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
314
315       if( !fsen.getIsCallerSESEplaceholder() ) {
316         allSESEs.add( fsen );
317       }
318
319       fsen.setfmEnclosing( fm );
320       fsen.setmdEnclosing( fm.getMethod() );
321       fsen.setcdEnclosing( fm.getMethod().getClassDesc() );
322
323       if( seseStack.empty() ) {
324         rootSESEs.add( fsen );
325         fsen.setParent( null );
326       } else {
327         seseStack.peek().addChild( fsen );
328         fsen.setParent( seseStack.peek() );
329       }
330
331       seseStack.push( fsen );
332     } break;
333
334     case FKind.FlatSESEExitNode: {
335       FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
336       assert !seseStack.empty();
337       FlatSESEEnterNode fsen = seseStack.pop();
338     } break;
339
340     case FKind.FlatReturnNode: {
341       FlatReturnNode frn = (FlatReturnNode) fn;
342       if( !seseStack.empty() &&
343           !seseStack.peek().getIsCallerSESEplaceholder() 
344         ) {
345         throw new Error( "Error: return statement enclosed within SESE "+
346                          seseStack.peek().getPrettyIdentifier() );
347       }
348     } break;
349       
350     }
351   }
352
353
354   private void livenessAnalysisBackward( FlatSESEEnterNode fsen, 
355                                          boolean toplevel, 
356                                          Hashtable< FlatSESEExitNode, Set<TempDescriptor> > liveout ) {
357
358     // start from an SESE exit, visit nodes in reverse up to
359     // SESE enter in a fixed-point scheme, where children SESEs
360     // should already be analyzed and therefore can be skipped 
361     // because child SESE enter node has all necessary info
362     Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
363
364     if( toplevel ) {
365       flatNodesToVisit.add( fsen.getfmEnclosing().getFlatExit() );
366     } else {
367       flatNodesToVisit.add( fsen.getFlatExit() );
368     }
369
370     Hashtable<FlatNode, Set<TempDescriptor>> livenessResults = 
371       new Hashtable< FlatNode, Set<TempDescriptor> >();
372
373     if( toplevel ) {
374       liveout = new Hashtable< FlatSESEExitNode, Set<TempDescriptor> >();
375     }
376
377     while( !flatNodesToVisit.isEmpty() ) {
378       FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
379       flatNodesToVisit.remove( fn );      
380       
381       Set<TempDescriptor> prev = livenessResults.get( fn );
382
383       // merge sets from control flow joins
384       Set<TempDescriptor> u = new HashSet<TempDescriptor>();
385       for( int i = 0; i < fn.numNext(); i++ ) {
386         FlatNode nn = fn.getNext( i );
387         Set<TempDescriptor> s = livenessResults.get( nn );
388         if( s != null ) {
389           u.addAll( s );
390         }
391       }
392       
393       Set<TempDescriptor> curr = liveness_nodeActions( fn, u, fsen, toplevel, liveout);
394
395       // if a new result, schedule backward nodes for analysis
396       if( !curr.equals( prev ) ) {
397         livenessResults.put( fn, curr );
398
399         // don't flow backwards past current SESE enter
400         if( !fn.equals( fsen ) ) {
401           for( int i = 0; i < fn.numPrev(); i++ ) {
402             FlatNode nn = fn.getPrev( i );
403             flatNodesToVisit.add( nn );
404           }
405         }
406       }
407     }
408     
409     Set<TempDescriptor> s = livenessResults.get( fsen );
410     if( s != null ) {
411       fsen.addInVarSet( s );
412     }
413     
414     // remember liveness per node from the root view as the
415     // global liveness of variables for later passes to use
416     if( toplevel ) {
417       livenessRootView.putAll( livenessResults );
418     }
419
420     // post-order traversal, so do children first
421     Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
422     while( childItr.hasNext() ) {
423       FlatSESEEnterNode fsenChild = childItr.next();
424       livenessAnalysisBackward( fsenChild, false, liveout );
425     }
426   }
427
428   private Set<TempDescriptor> liveness_nodeActions( FlatNode fn, 
429                                                     Set<TempDescriptor> liveIn,
430                                                     FlatSESEEnterNode currentSESE,
431                                                     boolean toplevel,
432                                                     Hashtable< FlatSESEExitNode, Set<TempDescriptor> > liveout 
433                                                   ) {
434     switch( fn.kind() ) {
435       
436     case FKind.FlatSESEExitNode:
437       if( toplevel ) {
438         FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
439         if( !liveout.containsKey( fsexn ) ) {
440           liveout.put( fsexn, new HashSet<TempDescriptor>() );
441         }
442         liveout.get( fsexn ).addAll( liveIn );
443       }
444       // no break, sese exits should also execute default actions
445       
446     default: {
447       // handle effects of statement in reverse, writes then reads
448       TempDescriptor [] writeTemps = fn.writesTemps();
449       for( int i = 0; i < writeTemps.length; ++i ) {
450         liveIn.remove( writeTemps[i] );
451         
452         if( !toplevel ) {
453           FlatSESEExitNode fsexn = currentSESE.getFlatExit();
454           Set<TempDescriptor> livetemps = liveout.get( fsexn );
455           if( livetemps != null &&
456               livetemps.contains( writeTemps[i] ) ) {
457             // write to a live out temp...
458             // need to put in SESE liveout set
459             currentSESE.addOutVar( writeTemps[i] );
460           }     
461         }
462       }
463
464       TempDescriptor [] readTemps = fn.readsTemps();
465       for( int i = 0; i < readTemps.length; ++i ) {
466         liveIn.add( readTemps[i] );
467       }
468       
469       Set<TempDescriptor> virtualReadTemps = livenessVirtualReads.get( fn );
470       if( virtualReadTemps != null ) {
471         liveIn.addAll( virtualReadTemps );
472       }     
473       
474     } break;
475
476     } // end switch
477
478     return liveIn;
479   }
480
481
482   private void variableAnalysisForward( FlatMethod fm ) {
483     
484     Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
485     flatNodesToVisit.add( fm );  
486
487     while( !flatNodesToVisit.isEmpty() ) {
488       FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
489       flatNodesToVisit.remove( fn );      
490
491       Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
492       assert seseStack != null;      
493
494       VarSrcTokTable prev = variableResults.get( fn );
495
496       // merge sets from control flow joins
497       VarSrcTokTable curr = new VarSrcTokTable();
498       for( int i = 0; i < fn.numPrev(); i++ ) {
499         FlatNode nn = fn.getPrev( i );          
500         VarSrcTokTable incoming = variableResults.get( nn );
501         curr.merge( incoming );
502       }
503
504       if( !seseStack.empty() ) {
505         variable_nodeActions( fn, curr, seseStack.peek() );
506       }
507
508       // if a new result, schedule forward nodes for analysis
509       if( !curr.equals( prev ) ) {       
510         variableResults.put( fn, curr );
511
512         for( int i = 0; i < fn.numNext(); i++ ) {
513           FlatNode nn = fn.getNext( i );         
514           flatNodesToVisit.add( nn );    
515         }
516       }
517     }
518   }
519
520   private void variable_nodeActions( FlatNode fn, 
521                                      VarSrcTokTable vstTable,
522                                      FlatSESEEnterNode currentSESE ) {
523     switch( fn.kind() ) {
524
525     case FKind.FlatSESEEnterNode: {
526       FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
527       assert fsen.equals( currentSESE );
528
529       vstTable.age( currentSESE );
530       vstTable.assertConsistency();
531     } break;
532
533     case FKind.FlatSESEExitNode: {
534       FlatSESEExitNode  fsexn = (FlatSESEExitNode)  fn;
535       FlatSESEEnterNode fsen  = fsexn.getFlatEnter();
536       assert currentSESE.getChildren().contains( fsen );
537
538       vstTable.remapChildTokens( fsen );
539       
540       // liveness virtual reads are things that might be 
541       // written by an SESE and should be added to the in-set
542       // anything virtually read by this SESE should be pruned
543       // of parent or sibling sources
544       Set<TempDescriptor> liveVars         = livenessRootView.get( fn );
545       Set<TempDescriptor> fsenVirtReads    = vstTable.calcVirtReadsAndPruneParentAndSiblingTokens( fsen, liveVars );
546       Set<TempDescriptor> fsenVirtReadsOld = livenessVirtualReads.get( fn );
547       if( fsenVirtReadsOld != null ) {
548         fsenVirtReads.addAll( fsenVirtReadsOld );
549       }
550       livenessVirtualReads.put( fn, fsenVirtReads );
551
552
553       // then all child out-set tokens are guaranteed
554       // to be filled in, so clobber those entries with
555       // the latest, clean sources
556       Iterator<TempDescriptor> outVarItr = fsen.getOutVarSet().iterator();
557       while( outVarItr.hasNext() ) {
558         TempDescriptor outVar = outVarItr.next();
559         HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
560         ts.add( outVar );
561         VariableSourceToken vst = 
562           new VariableSourceToken( ts,
563                                    fsen,
564                                    new Integer( 0 ),
565                                    outVar
566                                    );
567         vstTable.remove( outVar );
568         vstTable.add( vst );
569       }
570       vstTable.assertConsistency();
571
572     } break;
573
574     case FKind.FlatOpNode: {
575       FlatOpNode fon = (FlatOpNode) fn;
576
577       if( fon.getOp().getOp() == Operation.ASSIGN ) {
578         TempDescriptor lhs = fon.getDest();
579         TempDescriptor rhs = fon.getLeft();        
580
581         vstTable.remove( lhs );
582
583         Set<VariableSourceToken> forAddition = new HashSet<VariableSourceToken>();
584
585         Iterator<VariableSourceToken> itr = vstTable.get( rhs ).iterator();
586         while( itr.hasNext() ) {
587           VariableSourceToken vst = itr.next();
588
589           HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
590           ts.add( lhs );
591
592           if( currentSESE.getChildren().contains( vst.getSESE() ) ) {
593             // if the source comes from a child, copy it over
594             forAddition.add( new VariableSourceToken( ts,
595                                                       vst.getSESE(),
596                                                       vst.getAge(),
597                                                       vst.getAddrVar()
598                                                       )
599                              );
600           } else {
601             // otherwise, stamp it as us as the source
602             forAddition.add( new VariableSourceToken( ts,
603                                                       currentSESE,
604                                                       new Integer( 0 ),
605                                                       lhs
606                                                       )
607                              );
608           }
609         }
610
611         vstTable.addAll( forAddition );
612
613         // only break if this is an ASSIGN op node,
614         // otherwise fall through to default case
615         vstTable.assertConsistency();
616         break;
617       }
618     }
619
620     // note that FlatOpNode's that aren't ASSIGN
621     // fall through to this default case
622     default: {
623       TempDescriptor [] writeTemps = fn.writesTemps();
624       if( writeTemps.length > 0 ) {
625
626
627         // for now, when writeTemps > 1, make sure
628         // its a call node, programmer enforce only
629         // doing stuff like calling a print routine
630         //assert writeTemps.length == 1;
631         if( writeTemps.length > 1 ) {
632           assert fn.kind() == FKind.FlatCall ||
633                  fn.kind() == FKind.FlatMethod;
634           break;
635         }
636
637         vstTable.remove( writeTemps[0] );
638
639         HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
640         ts.add( writeTemps[0] );
641
642         vstTable.add( new VariableSourceToken( ts,
643                                                currentSESE,
644                                                new Integer( 0 ),
645                                                writeTemps[0]
646                                              )
647                       );
648       }      
649
650       vstTable.assertConsistency();
651     } break;
652
653     } // end switch
654   }
655
656
657   private void pruneVariableResultsWithLiveness( FlatMethod fm ) {
658     
659     // start from flat method top, visit every node in
660     // method exactly once
661     Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
662     flatNodesToVisit.add( fm );
663
664     Set<FlatNode> visited = new HashSet<FlatNode>();    
665
666     while( !flatNodesToVisit.isEmpty() ) {
667       Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
668       FlatNode fn = fnItr.next();
669
670       flatNodesToVisit.remove( fn );
671       visited.add( fn );      
672
673       Set<TempDescriptor> rootLiveSet = livenessRootView.get( fn );
674       VarSrcTokTable      vstTable    = variableResults.get( fn );
675       
676       vstTable.pruneByLiveness( rootLiveSet );
677       
678       for( int i = 0; i < fn.numNext(); i++ ) {
679         FlatNode nn = fn.getNext( i );
680
681         if( !visited.contains( nn ) ) {
682           flatNodesToVisit.add( nn );
683         }
684       }
685     }
686   }
687
688
689   private void notAvailableForward( FlatMethod fm ) {
690
691     Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
692     flatNodesToVisit.add( fm );  
693
694     while( !flatNodesToVisit.isEmpty() ) {
695       FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
696       flatNodesToVisit.remove( fn );      
697
698       Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
699       assert seseStack != null;      
700
701       Set<TempDescriptor> prev = notAvailableResults.get( fn );
702
703       Set<TempDescriptor> curr = new HashSet<TempDescriptor>();      
704       for( int i = 0; i < fn.numPrev(); i++ ) {
705         FlatNode nn = fn.getPrev( i );       
706         Set<TempDescriptor> notAvailIn = notAvailableResults.get( nn );
707         if( notAvailIn != null ) {
708           curr.addAll( notAvailIn );
709         }
710       }
711       
712       if( !seseStack.empty() ) {
713         notAvailable_nodeActions( fn, curr, seseStack.peek() );     
714       }
715
716       // if a new result, schedule forward nodes for analysis
717       if( !curr.equals( prev ) ) {
718         notAvailableResults.put( fn, curr );
719
720         for( int i = 0; i < fn.numNext(); i++ ) {
721           FlatNode nn = fn.getNext( i );         
722           flatNodesToVisit.add( nn );    
723         }
724       }
725     }
726   }
727
728   private void notAvailable_nodeActions( FlatNode fn, 
729                                          Set<TempDescriptor> notAvailSet,
730                                          FlatSESEEnterNode currentSESE ) {
731
732     // any temps that are removed from the not available set
733     // at this node should be marked in this node's code plan
734     // as temps to be grabbed at runtime!
735
736     switch( fn.kind() ) {
737
738     case FKind.FlatSESEEnterNode: {
739       FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
740       assert fsen.equals( currentSESE );
741       notAvailSet.clear();
742     } break;
743
744     case FKind.FlatSESEExitNode: {
745       FlatSESEExitNode  fsexn = (FlatSESEExitNode)  fn;
746       FlatSESEEnterNode fsen  = fsexn.getFlatEnter();
747       assert currentSESE.getChildren().contains( fsen );
748       notAvailSet.addAll( fsen.getOutVarSet() );
749     } break;
750
751     case FKind.FlatMethod: {
752       notAvailSet.clear();
753     }
754
755     case FKind.FlatOpNode: {
756       FlatOpNode fon = (FlatOpNode) fn;
757
758       if( fon.getOp().getOp() == Operation.ASSIGN ) {
759         TempDescriptor lhs = fon.getDest();
760         TempDescriptor rhs = fon.getLeft();
761
762         // copy makes lhs same availability as rhs
763         if( notAvailSet.contains( rhs ) ) {
764           notAvailSet.add( lhs );
765         } else {
766           notAvailSet.remove( lhs );
767         }
768
769         // only break if this is an ASSIGN op node,
770         // otherwise fall through to default case
771         break;
772       }
773     }
774
775     // note that FlatOpNode's that aren't ASSIGN
776     // fall through to this default case
777     default: {
778       TempDescriptor [] writeTemps = fn.writesTemps();
779       for( int i = 0; i < writeTemps.length; i++ ) {
780         TempDescriptor wTemp = writeTemps[i];
781         notAvailSet.remove( wTemp );
782       }
783       TempDescriptor [] readTemps = fn.readsTemps();
784       for( int i = 0; i < readTemps.length; i++ ) {
785         TempDescriptor rTemp = readTemps[i];
786         notAvailSet.remove( rTemp );
787
788         // if this variable has exactly one source, potentially
789         // get other things from this source as well
790         VarSrcTokTable vstTable = variableResults.get( fn );
791
792         Integer srcType = 
793           vstTable.getRefVarSrcType( rTemp, 
794                                      currentSESE,
795                                      currentSESE.getParent() );
796
797         if( srcType.equals( VarSrcTokTable.SrcType_STATIC ) ) {
798
799           VariableSourceToken vst = vstTable.get( rTemp ).iterator().next();
800
801           Iterator<VariableSourceToken> availItr = vstTable.get( vst.getSESE(),
802                                                                  vst.getAge()
803                                                                  ).iterator();
804
805           // look through things that are also available from same source
806           while( availItr.hasNext() ) {
807             VariableSourceToken vstAlsoAvail = availItr.next();
808           
809             Iterator<TempDescriptor> refVarItr = vstAlsoAvail.getRefVars().iterator();
810             while( refVarItr.hasNext() ) {
811               TempDescriptor refVarAlso = refVarItr.next();
812
813               // if a variable is available from the same source, AND it ALSO
814               // only comes from one statically known source, mark it available
815               Integer srcTypeAlso = 
816                 vstTable.getRefVarSrcType( refVarAlso, 
817                                            currentSESE,
818                                            currentSESE.getParent() );
819               if( srcTypeAlso.equals( VarSrcTokTable.SrcType_STATIC ) ) {
820                 notAvailSet.remove( refVarAlso );
821               }
822             }
823           }
824         }
825       }
826     } break;
827
828     } // end switch
829   }
830   
831   private void debugFunction(OwnershipAnalysis oa2, FlatMethod fm) {
832           
833           String methodName="SomeWork";
834           
835           MethodDescriptor md=fm.getMethod();
836                 HashSet<MethodContext> mcSet=oa2.getAllMethodContextSetByDescriptor(md);
837                 Iterator<MethodContext> mcIter=mcSet.iterator();
838                 
839                 while(mcIter.hasNext()){
840                         MethodContext mc=mcIter.next();
841                         
842                         OwnershipGraph og=oa2.getOwnvershipGraphByMethodContext(mc);
843                         
844                         if(fm.toString().indexOf(methodName)>0){
845                                  try {
846                                    og.writeGraph(fm.toString() + "SECONDGRAPH",
847                                                  true,  // write labels (variables)
848                                                  true,  // selectively hide intermediate temp vars
849                                                  true,  // prune unreachable heap regions
850                                                  false, // show back edges to confirm graph validity
851                                                  false, // show parameter indices (unmaintained!)
852                                                  true,  // hide subset reachability states
853                                                  false);// hide edge taints                              
854                                  } catch (IOException e) {
855                                  System.out.println("Error writing debug capture.");
856                                  System.exit(0);
857                                  }
858                         }
859                         
860
861
862                 }
863           
864   }
865   
866         private void methodEffects(FlatMethod fm, CallGraph callGraph) {
867
868                 MethodDescriptor md=fm.getMethod();
869                 HashSet<MethodContext> mcSet=ownAnalysis.getAllMethodContextSetByDescriptor(md);
870                 Iterator<MethodContext> mcIter=mcSet.iterator();
871                 
872                 while(mcIter.hasNext()){
873                         MethodContext mc=mcIter.next();
874                         
875                         Set<FlatNode> visited = new HashSet<FlatNode>();
876                         
877                         Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
878                         flatNodesToVisit.add(fm);
879
880                         while (!flatNodesToVisit.isEmpty()) {
881                                 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
882                                 flatNodesToVisit.remove(fn);
883
884                                 Stack<FlatSESEEnterNode> seseStack = seseStacks.get(fn);
885                                 assert seseStack != null;
886
887                                 if (!seseStack.empty()) {
888                                         effects_nodeActions(mc, fn, seseStack.peek(), callGraph);
889                                 }
890
891                                 flatNodesToVisit.remove(fn);
892                                 visited.add(fn);
893
894                                 for (int i = 0; i < fn.numNext(); i++) {
895                                         FlatNode nn = fn.getNext(i);
896                                         if (!visited.contains(nn)) {
897                                                 flatNodesToVisit.add(nn);
898                                         }
899                                 }
900
901                         }
902                         
903                         
904                 }
905                 
906         }
907         
908         private void analyzeRelatedAllocationSite(MethodDescriptor callerMD,
909                         MethodContext calleeMC, HashSet<Integer> paramIndexSet,
910                         HashSet<HeapRegionNode> visitedHRN) {
911
912                 HashSet<MethodContext> mcSet = ownAnalysis
913                                 .getAllMethodContextSetByDescriptor(callerMD);
914
915                 if (mcSet != null) {
916
917                         Iterator<MethodContext> mcIter = mcSet.iterator();
918
919                         FlatMethod callerFM = state.getMethodFlat(callerMD);
920
921                         while (mcIter.hasNext()) {
922                                 MethodContext mc = mcIter.next();
923
924                                 Set<FlatNode> visited = new HashSet<FlatNode>();
925                                 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
926                                 flatNodesToVisit.add(callerFM);
927
928                                 while (!flatNodesToVisit.isEmpty()) {
929                                         FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
930                                         flatNodesToVisit.remove(fn);
931
932                                         analyzeRelatedAllocationSite_NodeAction(fn, mc, calleeMC,
933                                                         paramIndexSet,visitedHRN);
934
935                                         flatNodesToVisit.remove(fn);
936                                         visited.add(fn);
937
938                                         for (int i = 0; i < fn.numNext(); i++) {
939                                                 FlatNode nn = fn.getNext(i);
940                                                 if (!visited.contains(nn)) {
941                                                         flatNodesToVisit.add(nn);
942                                                 }
943                                         }
944                                 }
945                         }
946                 }
947
948         }
949         
950         private void analyzeRelatedAllocationSite_NodeAction(FlatNode fn, MethodContext callerMC,
951  MethodContext calleeMC,
952                         HashSet<Integer> paramIndexSet, HashSet<HeapRegionNode> visitedHRN) {
953
954                 OwnershipGraph og = ownAnalysis
955                                 .getOwnvershipGraphByMethodContext(callerMC);
956
957                 switch (fn.kind()) {
958
959                 case FKind.FlatCall: {
960
961                         FlatCall fc = (FlatCall) fn;
962                         
963                         
964                         if(fc.numArgs()>0 && fc.getMethod().equals(calleeMC.getDescriptor())){
965                                 MethodContext calleeMCfromOG = ownAnalysis.getCalleeMethodContext(
966                                                 callerMC, fc);
967
968                                 // disable below condition. currently collect all possible
969                                 // allocation sites without regarding method context
970
971                                 // if (calleeMC.equals(calleeMCfromOG)) { // in this case, this
972                                 // method context calls corresponding callee.
973
974                                 int base;
975                                 if (((MethodDescriptor) calleeMC.getDescriptor()).isStatic()) {
976                                         base = 0;
977                                 } else {
978                                         base = 1;
979                                 }
980
981                                 for (Iterator iterator = paramIndexSet.iterator(); iterator
982                                                 .hasNext();) {
983                                         Integer integer = (Integer) iterator.next();
984
985                                         int paramIdx = integer - base;
986                                         if (paramIdx >= 0) {
987                                                 // if paramIdx is less than 0, assumes that it is
988                                                 // related with wrong method contexts.
989                                                 TempDescriptor arg = fc.getArg(paramIdx);
990                                                 LabelNode argLN = og.td2ln.get(arg);
991                                                 if (argLN != null) {
992                                                         Iterator<ReferenceEdge> iterEdge = argLN
993                                                                         .iteratorToReferencees();
994                                                         while (iterEdge.hasNext()) {
995                                                                 ReferenceEdge referenceEdge = (ReferenceEdge) iterEdge
996                                                                                 .next();
997
998                                                                 HeapRegionNode dstHRN = referenceEdge.getDst();
999                                                                 if (dstHRN.isParameter()) {
1000                                                                         if (!visitedHRN.contains(dstHRN)) {
1001                                                                                 setupRelatedAllocSiteAnalysis(og, callerMC,
1002                                                                                                 dstHRN, visitedHRN);
1003                                                                         }
1004                                                                 } else {
1005                                                                         addLiveInAllocationSite(callerMC, dstHRN
1006                                                                                         .getAllocationSite());
1007                                                                 }
1008                                                         }
1009                                                 }
1010                                         }
1011                                 }
1012                         }
1013                         
1014
1015                         // }
1016
1017                 }
1018                         break;
1019
1020                 }
1021         }
1022         
1023         private void setupRelatedAllocSiteAnalysis(OwnershipGraph og,
1024                         MethodContext mc, HeapRegionNode dstHRN,
1025                         HashSet<HeapRegionNode> visitedHRN) {
1026
1027                 HashSet<Integer> paramIndexSet = new HashSet<Integer>();
1028
1029                 // collect corresponding param index
1030                 Set<Integer> pIndexSet = og.idPrimary2paramIndexSet.get(dstHRN.getID());
1031                 if (pIndexSet != null) {
1032                         for (Iterator iterator = pIndexSet.iterator(); iterator.hasNext();) {
1033                                 Integer integer = (Integer) iterator.next();
1034                                 paramIndexSet.add(integer);
1035                         }
1036                 }
1037
1038                 Set<Integer> sIndexSet = og.idSecondary2paramIndexSet.get(dstHRN
1039                                 .getID());
1040                 if (sIndexSet != null) {
1041                         for (Iterator iterator = sIndexSet.iterator(); iterator.hasNext();) {
1042                                 Integer integer = (Integer) iterator.next();
1043                                 paramIndexSet.add(integer);
1044                         }
1045                 }
1046
1047                 if (mc.getDescriptor() instanceof MethodDescriptor) {
1048                         Set callerSet = callGraph.getCallerSet((MethodDescriptor) mc
1049                                         .getDescriptor());
1050                         for (Iterator iterator = callerSet.iterator(); iterator.hasNext();) {
1051                                 Object obj = (Object) iterator.next();
1052                                 if (obj instanceof MethodDescriptor) {
1053                                         MethodDescriptor callerMD = (MethodDescriptor) obj;
1054
1055                                         if(callerMD.equals(mc.getDescriptor())){
1056                                                 continue;
1057                                         }
1058                                         analyzeRelatedAllocationSite(callerMD, mc, paramIndexSet,visitedHRN);
1059
1060                                 }
1061                         }
1062                 }
1063         }
1064   
1065         private void effects_nodeActions(MethodContext mc, FlatNode fn,
1066                         FlatSESEEnterNode currentSESE, CallGraph callGraph) {
1067
1068                 OwnershipGraph og = ownAnalysis.getOwnvershipGraphByMethodContext(mc);
1069
1070                 switch (fn.kind()) {
1071
1072                 case FKind.FlatSESEEnterNode: {
1073
1074                         FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
1075                         assert fsen.equals(currentSESE);
1076
1077                         // uniquely taint each live-in variable
1078                         Set<TempDescriptor> set = fsen.getInVarSet();
1079                         Iterator<TempDescriptor> iter = set.iterator();
1080                         int idx = 0;
1081                         while (iter.hasNext()) {
1082                                 TempDescriptor td = iter.next();
1083                                 LabelNode ln = og.td2ln.get(td);
1084                                 if (ln != null) {
1085                                         int taint = (int) Math.pow(2, idx);
1086                                         taintLabelNode(ln, taint);
1087
1088                                         // collects related allocation sites
1089                                         Iterator<ReferenceEdge> referenceeIter = ln
1090                                                         .iteratorToReferencees();
1091                                         while (referenceeIter.hasNext()) {
1092                                                 ReferenceEdge referenceEdge = (ReferenceEdge) referenceeIter
1093                                                                 .next();
1094                                                 HeapRegionNode dstHRN = referenceEdge.getDst();
1095                                                 if (dstHRN.isParameter()) {
1096                                                         
1097                                                         HashSet<HeapRegionNode> visitedHRN=new HashSet<HeapRegionNode>();
1098                                                         visitedHRN.add(dstHRN);
1099                                                         setupRelatedAllocSiteAnalysis(og,mc,dstHRN,visitedHRN);
1100
1101                                                 } else {
1102                                                         addLiveInAllocationSite(mc, dstHRN
1103                                                                         .getAllocationSite());
1104                                                 }
1105                                         }
1106
1107                                 }
1108
1109                                 idx++;
1110                         }
1111
1112                 }
1113                         break;
1114
1115                 case FKind.FlatSESEExitNode: {
1116                         FlatSESEExitNode fsexit = (FlatSESEExitNode) fn;
1117
1118                         FlatSESEEnterNode enterNode = fsexit.getFlatEnter();
1119                         FlatSESEEnterNode parent = enterNode.getParent();
1120                         if (parent != null) {
1121
1122                                 SESEEffectsSet set = enterNode.getSeseEffectsSet();
1123                                 Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> readTable = set
1124                                                 .getReadTable();
1125                                 Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> parentReadTable = parent
1126                                                 .getSeseEffectsSet().getReadTable();
1127                                 Set<TempDescriptor> keys = readTable.keySet();
1128                                 Iterator<TempDescriptor> keyIter = keys.iterator();
1129                                 while (keyIter.hasNext()) {
1130                                         TempDescriptor td = (TempDescriptor) keyIter.next();
1131                                         HashSet<SESEEffectsKey> effectsSet = readTable.get(td);
1132                                         HashSet<SESEEffectsKey> parentEffectsSet = parentReadTable
1133                                                         .get(td);
1134                                         if (parentEffectsSet == null) {
1135                                                 parentEffectsSet = new HashSet<SESEEffectsKey>();
1136                                         }
1137
1138                                         for (Iterator iterator = effectsSet.iterator(); iterator
1139                                                         .hasNext();) {
1140                                                 SESEEffectsKey seseKey = (SESEEffectsKey) iterator
1141                                                                 .next();
1142                                                 parentEffectsSet.add(new SESEEffectsKey(seseKey
1143                                                                 .getFieldDescriptor(), seseKey
1144                                                                 .getTypeDescriptor(), seseKey.getHRNId()));
1145                                         }
1146
1147                                         parentReadTable.put(td, parentEffectsSet);
1148                                 }
1149
1150                                 Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> writeTable = set
1151                                                 .getWriteTable();
1152                                 Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> parentWriteTable = parent
1153                                                 .getSeseEffectsSet().getWriteTable();
1154                                 keys = writeTable.keySet();
1155                                 keyIter = keys.iterator();
1156                                 while (keyIter.hasNext()) {
1157                                         TempDescriptor td = (TempDescriptor) keyIter.next();
1158                                         HashSet<SESEEffectsKey> effectsSet = writeTable.get(td);
1159                                         HashSet<SESEEffectsKey> parentEffectsSet = parentWriteTable
1160                                                         .get(td);
1161                                         if (parentEffectsSet == null) {
1162                                                 parentEffectsSet = new HashSet<SESEEffectsKey>();
1163                                         }
1164
1165                                         for (Iterator iterator = effectsSet.iterator(); iterator
1166                                                         .hasNext();) {
1167                                                 SESEEffectsKey seseKey = (SESEEffectsKey) iterator
1168                                                                 .next();
1169                                                 parentEffectsSet.add(new SESEEffectsKey(seseKey
1170                                                                 .getFieldDescriptor(), seseKey
1171                                                                 .getTypeDescriptor(), seseKey.getHRNId()));
1172                                         }
1173
1174                                         parentWriteTable.put(td, parentEffectsSet);
1175                                 }
1176
1177                                 Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> strongUpdateTable = set
1178                                                 .getStrongUpdateTable();
1179                                 Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> parentstrongUpdateTable = parent
1180                                                 .getSeseEffectsSet().getStrongUpdateTable();
1181                                 keys = strongUpdateTable.keySet();
1182                                 keyIter = keys.iterator();
1183                                 while (keyIter.hasNext()) {
1184                                         TempDescriptor td = (TempDescriptor) keyIter.next();
1185                                         HashSet<SESEEffectsKey> effectsSet = strongUpdateTable
1186                                                         .get(td);
1187                                         HashSet<SESEEffectsKey> parentEffectsSet = parentstrongUpdateTable
1188                                                         .get(td);
1189                                         if (parentEffectsSet == null) {
1190                                                 parentEffectsSet = new HashSet<SESEEffectsKey>();
1191                                         }
1192
1193                                         for (Iterator iterator = effectsSet.iterator(); iterator
1194                                                         .hasNext();) {
1195                                                 SESEEffectsKey seseKey = (SESEEffectsKey) iterator
1196                                                                 .next();
1197                                                 parentEffectsSet.add(new SESEEffectsKey(seseKey
1198                                                                 .getFieldDescriptor(), seseKey
1199                                                                 .getTypeDescriptor(), seseKey.getHRNId()));
1200                                         }
1201
1202                                         parentstrongUpdateTable.put(td, parentEffectsSet);
1203                                 }
1204
1205                         }
1206
1207                 }
1208                         break;
1209
1210                 case FKind.FlatFieldNode: {
1211
1212                         FlatFieldNode ffn = (FlatFieldNode) fn;
1213                         TempDescriptor src = ffn.getSrc();
1214                         FieldDescriptor field = ffn.getField();
1215
1216                         LabelNode srcLN = og.td2ln.get(src);
1217                         if (srcLN != null) {
1218                                 HashSet<TempDescriptor> affectedTDSet = getAccessedTaintNodeSet(srcLN);
1219                                 Iterator<TempDescriptor> affectedIter = affectedTDSet
1220                                                 .iterator();
1221                                 while (affectedIter.hasNext()) {
1222                                         TempDescriptor affectedTD = affectedIter.next();
1223
1224                                         if (currentSESE.getInVarSet().contains(affectedTD)) {
1225
1226                                                 HashSet<HeapRegionNode> hrnSet = getReferenceHeapIDSet(
1227                                                                 og, affectedTD);
1228                                                 Iterator<HeapRegionNode> hrnIter = hrnSet.iterator();
1229                                                 while (hrnIter.hasNext()) {
1230                                                         HeapRegionNode hrn = hrnIter.next();
1231
1232                                                         Iterator<ReferenceEdge> referencers = hrn
1233                                                                         .iteratorToReferencers();
1234                                                         while (referencers.hasNext()) {
1235                                                                 ReferenceEdge referenceEdge = (ReferenceEdge) referencers
1236                                                                                 .next();
1237                                                                 if (field.getSymbol().equals(
1238                                                                                 referenceEdge.getField())) {
1239                                                                         currentSESE.readEffects(affectedTD, field
1240                                                                                         .getSymbol(), src.getType(),
1241                                                                                         referenceEdge.getDst().getID());
1242                                                                 }
1243                                                         }
1244
1245                                                 }
1246                                         }
1247                                 }
1248
1249                                 // handle tainted case
1250
1251                                 Iterator<ReferenceEdge> edgeIter = srcLN
1252                                                 .iteratorToReferencees();
1253                                 while (edgeIter.hasNext()) {
1254                                         ReferenceEdge edge = edgeIter.next();
1255                                         HeapRegionNode accessHRN = edge.getDst();
1256                                         // / follow the chain of reference to identify possible
1257                                         // accesses
1258                                         Iterator<ReferenceEdge> referIter = accessHRN
1259                                                         .iteratorToReferencers();
1260                                         while (referIter.hasNext()) {
1261                                                 ReferenceEdge referEdge = (ReferenceEdge) referIter
1262                                                                 .next();
1263
1264                                                 // if (referEdge.getTaintIdentifier() >0 ||
1265                                                 // referEdge.getSESETaintIdentifier()>0 ) {
1266                                                 HashSet<TempDescriptor> referSet = new HashSet<TempDescriptor>();
1267                                                 followReference(accessHRN, referSet,
1268                                                                 new HashSet<HeapRegionNode>(), currentSESE);
1269
1270                                                 Iterator<TempDescriptor> referSetIter = referSet
1271                                                                 .iterator();
1272                                                 while (referSetIter.hasNext()) {
1273                                                         TempDescriptor tempDescriptor = (TempDescriptor) referSetIter
1274                                                                         .next();
1275                                                         currentSESE.readEffects(tempDescriptor, field
1276                                                                         .getSymbol(), src.getType(), accessHRN
1277                                                                         .getID());
1278                                                 }
1279                                                 // }
1280                                         }
1281                                         // /
1282                                         if (edge.getTaintIdentifier() > 0
1283                                                         || edge.getSESETaintIdentifier() > 0) {
1284
1285                                                 affectedTDSet = getReferenceNodeSet(accessHRN);
1286                                                 affectedIter = affectedTDSet.iterator();
1287                                                 while (affectedIter.hasNext()) {
1288                                                         TempDescriptor affectedTD = affectedIter.next();
1289
1290                                                         if (currentSESE.getInVarSet().contains(affectedTD)) {
1291
1292                                                                 HashSet<HeapRegionNode> hrnSet = getReferenceHeapIDSet(
1293                                                                                 og, affectedTD);
1294                                                                 Iterator<HeapRegionNode> hrnIter = hrnSet
1295                                                                                 .iterator();
1296                                                                 while (hrnIter.hasNext()) {
1297                                                                         HeapRegionNode hrn = hrnIter.next();
1298                                                                         currentSESE.readEffects(affectedTD, field
1299                                                                                         .getSymbol(), src.getType(), hrn
1300                                                                                         .getID());
1301                                                                 }
1302
1303                                                         }
1304
1305                                                 }
1306                                         }
1307                                 }
1308                         }
1309
1310                 }
1311                         break;
1312
1313                 case FKind.FlatSetFieldNode: {
1314
1315                         FlatSetFieldNode fsen = (FlatSetFieldNode) fn;
1316                         TempDescriptor dst = fsen.getDst();
1317                         FieldDescriptor field = fsen.getField();
1318
1319                         LabelNode dstLN = og.td2ln.get(dst);
1320                         if (dstLN != null) {
1321                                 // check possible strong updates
1322                                 boolean strongUpdate = false;
1323
1324                                 if (!field.getType().isImmutable() || field.getType().isArray()) {
1325                                         Iterator<ReferenceEdge> itrXhrn = dstLN
1326                                                         .iteratorToReferencees();
1327                                         while (itrXhrn.hasNext()) {
1328                                                 ReferenceEdge edgeX = itrXhrn.next();
1329                                                 HeapRegionNode hrnX = edgeX.getDst();
1330
1331                                                 // we can do a strong update here if one of two cases
1332                                                 // holds
1333                                                 if (field != null
1334                                                                 && field != OwnershipAnalysis
1335                                                                                 .getArrayField(field.getType())
1336                                                                 && ((hrnX.getNumReferencers() == 1) || // case 1
1337                                                                 (hrnX.isSingleObject() && dstLN
1338                                                                                 .getNumReferencees() == 1) // case 2
1339                                                                 )) {
1340                                                         strongUpdate = true;
1341                                                 }
1342                                         }
1343                                 }
1344
1345                                 HashSet<TempDescriptor> affectedTDSet = getAccessedTaintNodeSet(dstLN);
1346
1347                                 Iterator<TempDescriptor> affectedIter = affectedTDSet
1348                                                 .iterator();
1349
1350                                 while (affectedIter.hasNext()) {
1351                                         TempDescriptor affectedTD = affectedIter.next();
1352                                         if (currentSESE.getInVarSet().contains(affectedTD)) {
1353
1354                                                 HashSet<HeapRegionNode> hrnSet = getReferenceHeapIDSet(
1355                                                                 og, affectedTD);
1356                                                 Iterator<HeapRegionNode> hrnIter = hrnSet.iterator();
1357                                                 while (hrnIter.hasNext()) {
1358                                                         HeapRegionNode hrn = hrnIter.next();
1359
1360                                                         Iterator<ReferenceEdge> referencers = hrn
1361                                                                         .iteratorToReferencers();
1362                                                         while (referencers.hasNext()) {
1363                                                                 ReferenceEdge referenceEdge = (ReferenceEdge) referencers
1364                                                                                 .next();
1365                                                                 if (field.getSymbol().equals(
1366                                                                                 referenceEdge.getField())) {
1367                                                                         currentSESE.writeEffects(affectedTD, field
1368                                                                                         .getSymbol(), dst.getType(),
1369                                                                                         referenceEdge.getDst().getID(),
1370                                                                                         strongUpdate);
1371                                                                 }
1372                                                         }
1373
1374                                                 }
1375                                         }
1376                                 }
1377
1378                                 // handle tainted case
1379                                 Iterator<ReferenceEdge> edgeIter = dstLN
1380                                                 .iteratorToReferencees();
1381                                 while (edgeIter.hasNext()) {
1382                                         ReferenceEdge edge = edgeIter.next();
1383
1384                                         HeapRegionNode accessHRN = edge.getDst();
1385                                         // / follow the chain of reference to identify possible
1386                                         // accesses
1387                                         Iterator<ReferenceEdge> referIter = accessHRN
1388                                                         .iteratorToReferencers();
1389                                         while (referIter.hasNext()) {
1390                                                 ReferenceEdge referEdge = (ReferenceEdge) referIter
1391                                                                 .next();
1392
1393                                                 // if (referEdge.getTaintIdentifier() > 0 ||
1394                                                 // referEdge.getSESETaintIdentifier() > 0 ) {
1395                                                 HashSet<TempDescriptor> referSet = new HashSet<TempDescriptor>();
1396                                                 followReference(accessHRN, referSet,
1397                                                                 new HashSet<HeapRegionNode>(), currentSESE);
1398                                                 Iterator<TempDescriptor> referSetIter = referSet
1399                                                                 .iterator();
1400                                                 while (referSetIter.hasNext()) {
1401                                                         TempDescriptor tempDescriptor = (TempDescriptor) referSetIter
1402                                                                         .next();
1403                                                         currentSESE.writeEffects(tempDescriptor, field
1404                                                                         .getSymbol(), dst.getType(), accessHRN
1405                                                                         .getID(), strongUpdate);
1406                                                 }
1407                                                 // }
1408                                         }
1409                                         // /
1410                                         if (edge.getTaintIdentifier() > 0
1411                                                         || edge.getSESETaintIdentifier() > 0) {
1412                                                 affectedTDSet = getReferenceNodeSet(accessHRN);
1413                                                 affectedIter = affectedTDSet.iterator();
1414                                                 while (affectedIter.hasNext()) {
1415                                                         TempDescriptor affectedTD = affectedIter.next();
1416                                                         if (currentSESE.getInVarSet().contains(affectedTD)) {
1417
1418                                                                 HashSet<HeapRegionNode> hrnSet = getReferenceHeapIDSet(
1419                                                                                 og, affectedTD);
1420                                                                 Iterator<HeapRegionNode> hrnIter = hrnSet
1421                                                                                 .iterator();
1422                                                                 while (hrnIter.hasNext()) {
1423                                                                         HeapRegionNode hrn = hrnIter.next();
1424                                                                         currentSESE.writeEffects(affectedTD, field
1425                                                                                         .getSymbol(), dst.getType(), hrn
1426                                                                                         .getID(), strongUpdate);
1427
1428                                                                 }
1429
1430                                                         }
1431
1432                                                 }
1433                                         }
1434                                 }
1435
1436                         }
1437
1438                 }
1439                         break;
1440
1441                 case FKind.FlatCall: {
1442                         FlatCall fc = (FlatCall) fn;
1443
1444                         MethodContext calleeMC = ownAnalysis.getCalleeMethodContext(mc, fc);
1445
1446                         MethodEffects me = ownAnalysis.getMethodEffectsAnalysis()
1447                                         .getMethodEffectsByMethodContext(calleeMC);
1448
1449                         OwnershipGraph calleeOG = ownAnalysis
1450                                         .getOwnvershipGraphByMethodContext(calleeMC);
1451
1452                         FlatMethod fm = state.getMethodFlat(fc.getMethod());
1453                         ParameterDecomposition decomp = new ParameterDecomposition(
1454                                         ownAnalysis, fc, fm, calleeMC, calleeOG, og);
1455
1456                         int base;
1457                         if (((MethodDescriptor) calleeMC.getDescriptor()).isStatic()) {
1458                                 base = 0;
1459                         } else {
1460                                 base = 1;
1461                         }
1462
1463                         for (int i = 0; i < fc.numArgs(); i++) {
1464
1465                                 TempDescriptor arg = fc.getArg(i);
1466                                 Set<EffectsKey> readSet = me.getEffects().getReadingSet(
1467                                                 i + base);
1468                                 Set<EffectsKey> writeSet = me.getEffects().getWritingSet(
1469                                                 i + base);
1470
1471                                 Set<EffectsKey> strongUpdateSet = me.getEffects()
1472                                                 .getStrongUpdateSet(i + base);
1473
1474                                 LabelNode argLN = og.td2ln.get(arg);
1475                                 if (argLN != null) {
1476                                         HashSet<TempDescriptor> affectedTDSet = getAccessedTaintNodeSet(argLN);
1477                                         Iterator<TempDescriptor> affectedIter = affectedTDSet
1478                                                         .iterator();
1479
1480                                         while (affectedIter.hasNext()) {
1481
1482                                                 TempDescriptor affectedTD = affectedIter.next();
1483                                                 if (currentSESE.getInVarSet().contains(affectedTD)) {
1484
1485                                                         if (readSet != null) {
1486                                                                 Iterator<EffectsKey> readIter = readSet
1487                                                                                 .iterator();
1488                                                                 while (readIter.hasNext()) {
1489                                                                         EffectsKey key = readIter.next();
1490                                                                         Set<Integer> hrnSet = getCallerHRNId(
1491                                                                                         new Integer(i + base), calleeOG,
1492                                                                                         key.getHRNId(), decomp);
1493                                                                         Iterator<Integer> hrnIter = hrnSet
1494                                                                                         .iterator();
1495                                                                         while (hrnIter.hasNext()) {
1496                                                                                 Integer hrnID = (Integer) hrnIter
1497                                                                                                 .next();
1498                                                                                 currentSESE.readEffects(affectedTD, key
1499                                                                                                 .getFieldDescriptor(), key
1500                                                                                                 .getTypeDescriptor(), hrnID);
1501                                                                         }
1502                                                                 }
1503                                                         }
1504
1505                                                         if (writeSet != null) {
1506                                                                 Iterator<EffectsKey> writeIter = writeSet
1507                                                                                 .iterator();
1508                                                                 while (writeIter.hasNext()) {
1509                                                                         EffectsKey key = writeIter.next();
1510
1511                                                                         Set<Integer> hrnSet = getCallerHRNId(
1512                                                                                         new Integer(i + base), calleeOG,
1513                                                                                         key.getHRNId(), decomp);
1514                                                                         Iterator<Integer> hrnIter = hrnSet
1515                                                                                         .iterator();
1516                                                                         while (hrnIter.hasNext()) {
1517                                                                                 Integer hrnID = (Integer) hrnIter
1518                                                                                                 .next();
1519                                                                                 currentSESE.writeEffects(affectedTD,
1520                                                                                                 key.getFieldDescriptor(), key
1521                                                                                                                 .getTypeDescriptor(),
1522                                                                                                 hrnID, false);
1523                                                                         }
1524
1525                                                                 }
1526                                                         }
1527
1528                                                         if (strongUpdateSet != null) {
1529                                                                 Iterator<EffectsKey> strongUpdateIter = strongUpdateSet
1530                                                                                 .iterator();
1531                                                                 while (strongUpdateIter.hasNext()) {
1532                                                                         EffectsKey key = strongUpdateIter.next();
1533
1534                                                                         Set<Integer> hrnSet = getCallerHRNId(
1535                                                                                         new Integer(i + base), calleeOG,
1536                                                                                         key.getHRNId(), decomp);
1537                                                                         Iterator<Integer> hrnIter = hrnSet
1538                                                                                         .iterator();
1539                                                                         while (hrnIter.hasNext()) {
1540                                                                                 Integer hrnID = (Integer) hrnIter
1541                                                                                                 .next();
1542                                                                                 currentSESE.writeEffects(affectedTD,
1543                                                                                                 key.getFieldDescriptor(), key
1544                                                                                                                 .getTypeDescriptor(),
1545                                                                                                 hrnID, true);
1546                                                                         }
1547
1548                                                                 }
1549                                                         }
1550
1551                                                 }
1552
1553                                         }
1554
1555                                 }
1556
1557                         }
1558
1559                 }
1560                         break;
1561
1562                 }
1563         }
1564         
1565         private void addLiveInAllocationSite(MethodContext mc, AllocationSite ac){
1566                 HashSet<AllocationSite> set=mapMethodContextToLiveInAllocationSiteSet.get(mc);
1567                 if(set==null){
1568                         set=new HashSet<AllocationSite>();                      
1569                 }
1570                 set.add(ac);
1571                 mapMethodContextToLiveInAllocationSiteSet.put(mc, set);
1572         }
1573         
1574         private void followReference(HeapRegionNode hrn,HashSet<TempDescriptor> tdSet, HashSet<HeapRegionNode> visited, FlatSESEEnterNode currentSESE){
1575                 
1576                 Iterator<ReferenceEdge> referIter=hrn.iteratorToReferencers();
1577                 // check whether hrn is referenced by TD
1578                 while (referIter.hasNext()) {
1579                         ReferenceEdge referEdge = (ReferenceEdge) referIter.next();
1580                         if(referEdge.getSrc() instanceof LabelNode){
1581                                 LabelNode ln=(LabelNode)referEdge.getSrc();
1582                                 if(currentSESE.getInVarSet().contains(ln.getTempDescriptor())){
1583                                         tdSet.add(ln.getTempDescriptor());
1584                                 }
1585                         }else if(referEdge.getSrc() instanceof HeapRegionNode){
1586                                 HeapRegionNode nextHRN=(HeapRegionNode)referEdge.getSrc();
1587                                 if(!visited.contains(nextHRN)){
1588                                         visited.add(nextHRN);
1589                                         followReference(nextHRN,tdSet,visited,currentSESE);                             
1590                                 }
1591                                 
1592                         }
1593                 }
1594                 
1595         }
1596         
1597         private Set<Integer> getCallerHRNId(Integer paramIdx,
1598                         OwnershipGraph calleeOG, Integer calleeHRNId,
1599                         ParameterDecomposition paramDecom) {
1600                 
1601                 Integer hrnPrimaryID = calleeOG.paramIndex2idPrimary.get(paramIdx);
1602                 Integer hrnSecondaryID = calleeOG.paramIndex2idSecondary.get(paramIdx);
1603                 
1604                 if (calleeHRNId.equals(hrnPrimaryID)) {
1605                         // it references to primary param heap region
1606                         return paramDecom.getParamObject_hrnIDs(paramIdx);
1607                 } else if (calleeHRNId.equals(hrnSecondaryID)) {
1608                         // it references to secondary param heap region
1609                         return paramDecom.getParamReachable_hrnIDs(paramIdx);
1610                 }
1611
1612                 return new HashSet<Integer>();
1613         }
1614         
1615         private void taintLabelNode(LabelNode ln, int identifier) {
1616
1617                 Iterator<ReferenceEdge> edgeIter = ln.iteratorToReferencees();
1618                 while (edgeIter.hasNext()) {
1619                         ReferenceEdge edge = edgeIter.next();
1620                         HeapRegionNode hrn = edge.getDst();
1621
1622                         Iterator<ReferenceEdge> edgeReferencerIter = hrn
1623                                         .iteratorToReferencers();
1624                         while (edgeReferencerIter.hasNext()) {
1625                                 ReferenceEdge referencerEdge = edgeReferencerIter.next();
1626                                 OwnershipNode node = referencerEdge.getSrc();
1627                                 if (node instanceof LabelNode) {
1628                                         referencerEdge.unionSESETaintIdentifier(identifier);
1629                                 }else if(node instanceof HeapRegionNode){
1630                                         referencerEdge.unionSESETaintIdentifier(identifier);
1631                                 }
1632                         }
1633
1634                 }
1635
1636         }
1637         
1638         private HashSet<TempDescriptor> getReferenceNodeSet(HeapRegionNode hrn){
1639                 
1640                 HashSet<TempDescriptor> returnSet=new HashSet<TempDescriptor>();
1641                 
1642                 Iterator<ReferenceEdge> edgeIter=hrn.iteratorToReferencers();
1643                 while(edgeIter.hasNext()){
1644                         ReferenceEdge edge=edgeIter.next();
1645                         if(edge.getSrc() instanceof LabelNode){
1646                                 LabelNode ln=(LabelNode)edge.getSrc();
1647                                 returnSet.add(ln.getTempDescriptor());
1648                         }
1649                 }
1650                 
1651                 return returnSet;
1652                 
1653         }
1654         
1655         
1656         private HashSet<HeapRegionNode> getReferenceHeapIDSet(OwnershipGraph og, TempDescriptor td){
1657                 
1658                 HashSet<HeapRegionNode> returnSet=new HashSet<HeapRegionNode>();
1659                 
1660                 LabelNode ln=og.td2ln.get(td);
1661                 if(ln!=null){
1662                         Iterator<ReferenceEdge> edgeIter=ln.iteratorToReferencees();
1663                         while(edgeIter.hasNext()){
1664                                 ReferenceEdge edge=edgeIter.next();
1665                                         HeapRegionNode hrn=edge.getDst();
1666                                         returnSet.add(hrn);
1667                         }
1668                 }
1669                 return returnSet;
1670         }
1671         
1672         
1673         private HashSet<TempDescriptor> getAccessedTaintNodeSet(LabelNode ln) {
1674
1675                 HashSet<TempDescriptor> returnSet = new HashSet<TempDescriptor>();
1676
1677                 Iterator<ReferenceEdge> edgeIter = ln.iteratorToReferencees();
1678                 while (edgeIter.hasNext()) {
1679                         ReferenceEdge edge = edgeIter.next();
1680                         HeapRegionNode hrn = edge.getDst();
1681
1682                         Iterator<ReferenceEdge> edgeReferencerIter = hrn
1683                                         .iteratorToReferencers();
1684                         while (edgeReferencerIter.hasNext()) {
1685                                 ReferenceEdge referencerEdge = edgeReferencerIter.next();
1686
1687                                 if (referencerEdge.getSrc() instanceof LabelNode) {
1688                                         if (!((LabelNode) referencerEdge.getSrc()).equals(ln)) {
1689
1690                                                 if (referencerEdge.getSESETaintIdentifier() > 0) {
1691                                                         TempDescriptor td = ((LabelNode) referencerEdge
1692                                                                         .getSrc()).getTempDescriptor();
1693                                                         returnSet.add(td);
1694                                                 }
1695                                         }
1696                                 }
1697                         }
1698
1699                 }
1700
1701                 return returnSet;
1702
1703         }
1704         
1705         private HashSet<ReferenceEdge> getRefEdgeSetReferenceToSameHRN(
1706                         OwnershipGraph og, TempDescriptor td) {
1707
1708                 HashSet<ReferenceEdge> returnSet = new HashSet<ReferenceEdge>();
1709
1710                 HashSet<HeapRegionNode> heapIDs = getReferenceHeapIDSet(og, td);
1711                 for (Iterator<HeapRegionNode> iterator = heapIDs.iterator(); iterator
1712                                 .hasNext();) {
1713                         HeapRegionNode heapRegionNode = (HeapRegionNode) iterator.next();
1714                         Iterator<ReferenceEdge> referenceeIter = heapRegionNode
1715                                         .iteratorToReferencees();
1716                         while (referenceeIter.hasNext()) {
1717                                 ReferenceEdge edge = (ReferenceEdge) referenceeIter.next();
1718                                 if (edge.getSrc() instanceof HeapRegionNode) {
1719                                         returnSet.add(edge);
1720                                 }
1721                         }
1722                 }
1723                 return returnSet;
1724         }
1725         
1726         private HashSet<TempDescriptor> getTempDescSetReferenceToSameHRN(
1727                         OwnershipGraph og, TempDescriptor td) {
1728
1729                 HashSet<TempDescriptor> returnSet = new HashSet<TempDescriptor>();
1730
1731                 HashSet<HeapRegionNode> heapIDs = getReferenceHeapIDSet(og, td);
1732                 for (Iterator<HeapRegionNode> iterator = heapIDs.iterator(); iterator
1733                                 .hasNext();) {
1734                         HeapRegionNode heapRegionNode = (HeapRegionNode) iterator.next();
1735                         Iterator<ReferenceEdge> referencerIter = heapRegionNode
1736                                         .iteratorToReferencers();
1737                         while (referencerIter.hasNext()) {
1738                                 ReferenceEdge edge = (ReferenceEdge) referencerIter.next();
1739                                 if (edge.getSrc() instanceof LabelNode) {
1740                                         LabelNode ln = (LabelNode) edge.getSrc();
1741                                         returnSet.add(ln.getTempDescriptor());
1742                                 }
1743                         }
1744                 }
1745                 return returnSet;
1746         }
1747         
1748         private void DFSVisit( MethodDescriptor md,
1749                          LinkedList<MethodDescriptor> sorted,
1750                         HashSet<MethodDescriptor> discovered, JavaCallGraph javaCallGraph) {
1751
1752                 discovered.add(md);
1753
1754                 Iterator itr = javaCallGraph.getCallerSet(md).iterator();
1755                 while (itr.hasNext()) {
1756                         MethodDescriptor mdCaller = (MethodDescriptor) itr.next();
1757
1758                         if (!discovered.contains(mdCaller)) {
1759                                 DFSVisit(mdCaller, sorted, discovered, javaCallGraph);
1760                         }
1761                 }
1762
1763                 sorted.addFirst(md);
1764         }
1765         
1766         
1767         private LinkedList<MethodDescriptor> topologicalSort(Set set,
1768                         JavaCallGraph javaCallGraph) {
1769                 HashSet<MethodDescriptor> discovered = new HashSet<MethodDescriptor>();
1770                 LinkedList<MethodDescriptor> sorted = new LinkedList<MethodDescriptor>();
1771
1772                 Iterator<MethodDescriptor> itr = set.iterator();
1773                 while (itr.hasNext()) {
1774                         MethodDescriptor md = itr.next();
1775
1776                         if (!discovered.contains(md)) {
1777                                 DFSVisit(md, sorted, discovered, javaCallGraph);
1778                         }
1779                 }
1780
1781                 return sorted;
1782         }
1783          
1784         
1785         private void seseConflictsForward(JavaCallGraph javaCallGraph) {
1786
1787                 Set methodCallSet = javaCallGraph.getAllMethods(typeUtil.getMain());
1788
1789                 // topologically sort java call chain so that leaf calls are ordered
1790                 // first
1791                 LinkedList<MethodDescriptor> sortedMethodCalls = topologicalSort(
1792                                 methodCallSet, javaCallGraph);
1793
1794                 for (Iterator iterator = sortedMethodCalls.iterator(); iterator
1795                                 .hasNext();) {
1796                         MethodDescriptor md = (MethodDescriptor) iterator.next();
1797
1798                         FlatMethod fm = state.getMethodFlat(md);
1799
1800                         HashSet<MethodContext> mcSet = ownAnalysis
1801                                         .getAllMethodContextSetByDescriptor(md);
1802                         Iterator<MethodContext> mcIter = mcSet.iterator();
1803
1804                         currentMethodSummary = new MethodSummary();
1805                         preeffectsSet = new HashSet<PreEffectsKey>();
1806
1807                         while (mcIter.hasNext()) {
1808                                 MethodContext mc = mcIter.next();
1809
1810                                 Set<FlatNode> visited = new HashSet<FlatNode>();
1811
1812                                 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
1813                                 flatNodesToVisit.add(fm);
1814
1815                                 while (!flatNodesToVisit.isEmpty()) {
1816                                         FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
1817                                         flatNodesToVisit.remove(fn);
1818                                         visited.add(fn);
1819
1820                                         ParentChildConflictsMap prevResult = conflictsResults
1821                                                         .get(fn);
1822
1823                                         // merge sets from control flow
1824                                         ParentChildConflictsMap currentConflictsMap = new ParentChildConflictsMap();
1825                                         for (int i = 0; i < fn.numPrev(); i++) {
1826                                                 FlatNode prevFlatNode = fn.getPrev(i);
1827                                                 ParentChildConflictsMap incoming = conflictsResults
1828                                                                 .get(prevFlatNode);
1829                                                 if (incoming != null) {
1830                                                         currentConflictsMap.merge(incoming);
1831                                                 }
1832                                         }
1833
1834                                         conflicts_nodeAction(mc, fn, callGraph, preeffectsSet,
1835                                                         currentConflictsMap);
1836
1837                                         // if we have a new result, schedule forward nodes for
1838                                         // analysis
1839                                         
1840                                         if(!currentConflictsMap.isAfterChildSESE()){
1841                                                 conflictsResults.put(fn, currentConflictsMap);
1842                                                 for (int i = 0; i < fn.numNext(); i++) {
1843                                                         FlatNode nn = fn.getNext(i);
1844                                                          if (!visited.contains(nn)) {
1845                                                                  flatNodesToVisit.add(nn);
1846                                                         }
1847                                                 }
1848                                         }else{
1849                                                 if (!currentConflictsMap.equals(prevResult)) {
1850                                                         conflictsResults.put(fn, currentConflictsMap);
1851                                                         for (int i = 0; i < fn.numNext(); i++) {
1852                                                                 FlatNode nn = fn.getNext(i);
1853                                                                 flatNodesToVisit.add(nn);
1854                                                         }
1855                                                 }
1856                                         }
1857                                         
1858                                 }
1859                         }
1860                         methodSummaryResults.put(fm, currentMethodSummary);
1861                 }
1862
1863         }
1864         
1865         private void conflicts_nodeAction(MethodContext mc, FlatNode fn,
1866                         CallGraph callGraph, HashSet<PreEffectsKey> preeffectsSet,ParentChildConflictsMap currentConflictsMap) {
1867
1868                 OwnershipGraph og = ownAnalysis.getOwnvershipGraphByMethodContext(mc);
1869
1870                 switch (fn.kind()) {
1871
1872                 case FKind.FlatSESEEnterNode: {
1873                         
1874                         FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
1875                         if (!fsen.getIsCallerSESEplaceholder()) {
1876                                 currentMethodSummary.increaseChildSESECount();
1877                         }
1878
1879                         if (currentMethodSummary.getChildSESECount() == 1) {
1880                                 // need to store pre-effects
1881                                 currentMethodSummary.getEffectsSet().addAll(preeffectsSet);
1882
1883                                 for (Iterator iterator = currentMethodSummary.getEffectsSet()
1884                                                 .iterator(); iterator.hasNext();) {
1885                                         PreEffectsKey preEffectsKey = (PreEffectsKey) iterator
1886                                                         .next();
1887                                 }
1888
1889                                 preeffectsSet.clear();
1890                         }
1891
1892                 }
1893                         break;
1894
1895                 case FKind.FlatSESEExitNode: {
1896                         
1897                         FlatSESEExitNode fsen = (FlatSESEExitNode) fn;
1898                         
1899                         if (!fsen.getFlatEnter().getIsCallerSESEplaceholder()) {
1900                                 // all object variables are inaccessible.
1901                                 currentConflictsMap.setAfterChildSESE(true);
1902                                 currentConflictsMap = new ParentChildConflictsMap();
1903                         }
1904                 
1905                 }
1906                         break;
1907
1908                 case FKind.FlatNew: {
1909
1910                         if (currentConflictsMap.isAfterChildSESE()) {
1911                                 FlatNew fnew = (FlatNew) fn;
1912                                 TempDescriptor dst = fnew.getDst();
1913                                 currentConflictsMap.addAccessibleVar(dst);
1914                         }
1915
1916                 }
1917                         break;
1918
1919                 case FKind.FlatFieldNode: {
1920
1921                         FlatFieldNode ffn = (FlatFieldNode) fn;
1922                         TempDescriptor dst = ffn.getDst();
1923                         TempDescriptor src = ffn.getSrc();
1924                         FieldDescriptor field = ffn.getField();
1925
1926                         if (currentConflictsMap.isAfterChildSESE()) {
1927
1928                                 HashSet<TempDescriptor> srcTempSet = getTempDescSetReferenceToSameHRN(
1929                                                 og, src);
1930                                 for (Iterator iterator = srcTempSet.iterator(); iterator
1931                                                 .hasNext();) {
1932                                         TempDescriptor possibleSrc = (TempDescriptor) iterator
1933                                                         .next();
1934                                         if (!currentConflictsMap.isAccessible(possibleSrc)) {
1935                                                 HashSet<HeapRegionNode> refHRN=getReferenceHeapIDSet(og, possibleSrc);
1936                                                 currentConflictsMap.addStallSite(possibleSrc,refHRN);
1937                                         }
1938
1939                                         currentConflictsMap.addAccessibleVar(possibleSrc);
1940
1941                                         // contribute read effect on source's stall site
1942                                         currentConflictsMap.contributeEffect(src, field.getType()
1943                                                         .getSafeSymbol(), field.toString(),
1944                                                         StallSite.READ_EFFECT);
1945                                 }
1946
1947                                 HashSet<TempDescriptor> dstTempSet = getTempDescSetReferenceToSameHRN(
1948                                                 og, dst);
1949                                 for (Iterator iterator = dstTempSet.iterator(); iterator
1950                                                 .hasNext();) {
1951                                         TempDescriptor possibleDst = (TempDescriptor) iterator
1952                                                         .next();
1953                                         currentConflictsMap.addAccessibleVar(possibleDst);
1954                                 }
1955                         }
1956
1957                         if (currentMethodSummary.getChildSESECount() == 0) {
1958                                 // analyze preeffects
1959                                 preEffectAnalysis(og, src, field, PreEffectsKey.READ_EFFECT);
1960                         }
1961
1962                 }
1963                         break;
1964
1965                 case FKind.FlatSetFieldNode: {
1966
1967                         FlatSetFieldNode fsen = (FlatSetFieldNode) fn;
1968                         TempDescriptor dst = fsen.getDst();
1969                         FieldDescriptor field = fsen.getField();
1970                         TempDescriptor src = fsen.getSrc();
1971                         
1972                         if (currentConflictsMap.isAfterChildSESE()) {
1973
1974                                 HashSet<TempDescriptor> srcTempSet = getTempDescSetReferenceToSameHRN(
1975                                                 og, src);
1976                                 for (Iterator iterator = srcTempSet.iterator(); iterator
1977                                                 .hasNext();) {
1978                                         TempDescriptor possibleSrc = (TempDescriptor) iterator
1979                                                         .next();
1980                                         if (!currentConflictsMap.isAccessible(possibleSrc)) {
1981                                                 HashSet<HeapRegionNode> refHRN=getReferenceHeapIDSet(og, possibleSrc);
1982                                                 currentConflictsMap.addStallSite(possibleSrc,refHRN);
1983                                         }
1984                                         currentConflictsMap.addAccessibleVar(possibleSrc);
1985                                 }
1986
1987                                 HashSet<TempDescriptor> dstTempSet = getTempDescSetReferenceToSameHRN(
1988                                                 og, dst);
1989                                 for (Iterator iterator = dstTempSet.iterator(); iterator
1990                                                 .hasNext();) {
1991                                         TempDescriptor possibleDst = (TempDescriptor) iterator
1992                                                         .next();
1993
1994                                         if (!currentConflictsMap.isAccessible(possibleDst)) {
1995                                                 HashSet<HeapRegionNode> refHRN=getReferenceHeapIDSet(og, possibleDst);
1996                                                 currentConflictsMap.addStallSite(possibleDst,refHRN);
1997                                         }
1998                                         currentConflictsMap.addAccessibleVar(possibleDst);
1999                                         // contribute write effect on destination's stall site
2000                                         currentConflictsMap.contributeEffect(possibleDst, field
2001                                                         .getType().getSafeSymbol(), field.toString(),
2002                                                         StallSite.WRITE_EFFECT);
2003                                 }
2004
2005                                 // TODO need to create edge mapping for newly created edge
2006                                 HashSet<ReferenceEdge> edges = getRefEdgeSetReferenceToSameHRN(
2007                                                 og, dst);
2008
2009                                 StallSite ss = currentConflictsMap.getStallMap().get(dst);
2010                                 if (ss != null) {
2011                                         for (Iterator iterator = edges.iterator(); iterator
2012                                                         .hasNext();) {
2013                                                 ReferenceEdge referenceEdge = (ReferenceEdge) iterator
2014                                                                 .next();
2015                                                 if(!(referenceEdge.getSrc() instanceof LabelNode)){
2016                                                         currentConflictsMap.addStallEdge(referenceEdge, ss);
2017                                                 }
2018                                         }
2019                                 }
2020                         }
2021
2022                         if (currentMethodSummary.getChildSESECount() == 0) {
2023                                 // analyze preeffects
2024                                 preEffectAnalysis(og, dst, field, PreEffectsKey.WRITE_EFFECT);
2025                         }
2026
2027                 }
2028                         break;
2029
2030                 case FKind.FlatOpNode: {
2031                         if (currentConflictsMap.isAfterChildSESE()) {
2032
2033                                 // destination variable gets the status of source.
2034                                 FlatOpNode fon = (FlatOpNode) fn;
2035
2036                                 if (fon.getOp().getOp() == Operation.ASSIGN) {
2037
2038                                         TempDescriptor dst = fon.getDest();
2039                                         TempDescriptor src = fon.getLeft();
2040
2041                                         Integer sourceStatus = currentConflictsMap
2042                                                         .getAccessibleMap().get(src);
2043                                         if (sourceStatus == null) {
2044                                                 sourceStatus = ParentChildConflictsMap.INACCESSIBLE;
2045                                         }
2046
2047                                         HashSet<TempDescriptor> dstTempSet = getTempDescSetReferenceToSameHRN(
2048                                                         og, dst);
2049
2050                                         for (Iterator<TempDescriptor> iterator = dstTempSet
2051                                                         .iterator(); iterator.hasNext();) {
2052                                                 TempDescriptor possibleDst = iterator.next();
2053
2054                                                 if (sourceStatus
2055                                                                 .equals(ParentChildConflictsMap.ACCESSIBLE)) {
2056                                                         currentConflictsMap.addAccessibleVar(possibleDst);
2057                                                 } else {
2058                                                         currentConflictsMap.addInaccessibleVar(possibleDst);
2059
2060                                                 }
2061
2062                                         }
2063                                 }
2064
2065                         }
2066                 }
2067                         break;
2068
2069                 case FKind.FlatCall: {
2070
2071                         FlatCall fc = (FlatCall) fn;
2072
2073                         FlatMethod calleeFM = state.getMethodFlat(fc.getMethod());
2074
2075                         // retrieve callee's method summary
2076                         MethodSummary calleeMethodSummary = methodSummaryResults
2077                                         .get(calleeFM);
2078
2079                         if (calleeMethodSummary != null
2080                                         && calleeMethodSummary.getChildSESECount() > 0) {
2081
2082                                 // when parameter variable is accessible,
2083                                 // use callee's preeffects to figure out about how it affects
2084                                 // caller's stall site
2085
2086                                 for (int i = 0; i < fc.numArgs(); i++) {
2087                                         TempDescriptor paramTemp = fc.getArg(i);
2088
2089                                         if (currentConflictsMap.isAfterChildSESE()) {
2090                                                 if (currentConflictsMap.isAccessible(paramTemp)
2091                                                                 && currentConflictsMap.hasStallSite(paramTemp)) {
2092                                                         // preeffect contribute its effect to caller's stall
2093                                                         // site
2094
2095                                                         int offset = 0;
2096                                                         if (!fc.getMethod().isStatic()) {
2097                                                                 offset = 1;
2098                                                         }
2099
2100                                                         HashSet<PreEffectsKey> preeffectSet = calleeMethodSummary
2101                                                                         .getEffectsSetByParamIdx(i + offset);
2102
2103                                                         for (Iterator iterator = preeffectSet.iterator(); iterator
2104                                                                         .hasNext();) {
2105                                                                 PreEffectsKey preEffectsKey = (PreEffectsKey) iterator
2106                                                                                 .next();
2107                                                                 currentConflictsMap.contributeEffect(paramTemp,
2108                                                                                 preEffectsKey.getType(), preEffectsKey
2109                                                                                                 .getField(), preEffectsKey
2110                                                                                                 .getEffectType());
2111                                                         }
2112                                                 }
2113                                         }
2114                                         // in other cases, child SESE has not been discovered,
2115                                         // assumes that all variables are accessible
2116
2117                                 }
2118
2119                                 // If callee has at least one child sese, all parent object
2120                                 // is going to be inaccessible.
2121                                 currentConflictsMap = new ParentChildConflictsMap();
2122
2123                                 TempDescriptor returnTemp = fc.getReturnTemp();
2124
2125                                 if (calleeMethodSummary.getReturnValueAccessibility().equals(
2126                                                 MethodSummary.ACCESSIBLE)) {
2127                                         // when return value is accessible, associate with its
2128                                         // stall site
2129                                         currentConflictsMap.addAccessibleVar(returnTemp);
2130                                         currentConflictsMap.addStallSite(returnTemp,
2131                                                         calleeMethodSummary.getReturnStallSite());
2132                                 } else if (calleeMethodSummary.getReturnValueAccessibility()
2133                                                 .equals(MethodSummary.INACCESSIBLE)) {
2134                                         // when return value is inaccessible
2135                                         currentConflictsMap.addInaccessibleVar(returnTemp);
2136                                 }
2137                                 
2138                                 
2139                                 // TODO: need to handle edge mappings from callee
2140                                 HashSet<Integer> stallParamIdx=calleeMethodSummary.getStallParamIdxSet();
2141                                 for (Iterator iterator = stallParamIdx.iterator(); iterator
2142                                                 .hasNext();) {
2143                                         Integer paramIdx = (Integer) iterator.next();
2144                                 }
2145                         }
2146
2147                 }
2148                         break;
2149
2150                 case FKind.FlatReturnNode: {
2151
2152                         FlatReturnNode frn = (FlatReturnNode) fn;
2153                         TempDescriptor returnTD = frn.getReturnTemp();
2154
2155                         if (returnTD != null) {
2156                                 if (!currentConflictsMap.isAfterChildSESE()) {
2157                                         // in this case, all variables are accessible. There are no
2158                                         // child SESEs.
2159                                 } else {
2160                                         if (currentConflictsMap.isAccessible(returnTD)) {
2161                                                 currentMethodSummary
2162                                                                 .setReturnValueAccessibility(MethodSummary.ACCESSIBLE);
2163                                                 StallSite returnStallSite = currentConflictsMap
2164                                                                 .getStallMap().get(returnTD);
2165                                                 currentMethodSummary
2166                                                                 .setReturnStallSite(returnStallSite);
2167                                         } else {
2168                                                 currentMethodSummary
2169                                                                 .setReturnValueAccessibility(MethodSummary.INACCESSIBLE);
2170                                         }
2171                                 }
2172                         }
2173                 }
2174                         break;
2175
2176                 case FKind.FlatExit: {
2177
2178                         // store method summary when it has at least one child SESE
2179                         if (currentMethodSummary.getChildSESECount() > 0) {
2180                                 // current flat method
2181                                 FlatMethod fm = state.getMethodFlat(mc.getDescriptor());
2182                                 Set<TempDescriptor> stallTempSet=currentConflictsMap.getStallMap().keySet();
2183                                 for (Iterator iterator = stallTempSet.iterator(); iterator
2184                                                 .hasNext();) {
2185                                         TempDescriptor stallTD = (TempDescriptor) iterator.next();
2186                                         StallSite ss = currentConflictsMap.getStallMap().get(
2187                                                         stallTD);
2188
2189                                         HashSet<HeapRegionNode> stallSiteHRNSet = ss.getHRNSet();
2190                                         for (Iterator iterator2 = stallSiteHRNSet.iterator(); iterator2
2191                                                         .hasNext();) {
2192                                                 HeapRegionNode stallSiteHRN = (HeapRegionNode) iterator2
2193                                                                 .next();
2194
2195                                                 if (stallSiteHRN.isParameter()) {
2196                                                         currentMethodSummary
2197                                                                         .addStallParamIdxSet(og.idPrimary2paramIndexSet
2198                                                                                         .get(stallSiteHRN.getID()));
2199                                                         currentMethodSummary
2200                                                                         .addStallParamIdxSet(og.idSecondary2paramIndexSet
2201                                                                                         .get(stallSiteHRN.getID()));
2202                                                 }
2203
2204                                         }
2205
2206                                 }
2207                                 methodSummaryResults.put(fm, currentMethodSummary);
2208                         }
2209
2210                 }
2211                         break;
2212
2213                 }
2214
2215         }
2216         
2217         private void preEffectAnalysis(OwnershipGraph og, TempDescriptor td,
2218                         FieldDescriptor field, Integer effectType) {
2219
2220                 // analyze preeffects
2221                 HashSet<HeapRegionNode> hrnSet = getReferenceHeapIDSet(og, td);
2222                 for (Iterator iterator = hrnSet.iterator(); iterator.hasNext();) {
2223                         HeapRegionNode hrn = (HeapRegionNode) iterator.next();
2224                         if (hrn.isParameter()) {
2225                                 // effects on param heap region
2226
2227                                 Set<Integer> paramSet = og.idPrimary2paramIndexSet.get(hrn
2228                                                 .getID());
2229
2230                                 if (paramSet != null) {
2231                                         Iterator<Integer> paramIter = paramSet.iterator();
2232                                         while (paramIter.hasNext()) {
2233                                                 Integer paramID = paramIter.next();
2234                                                 PreEffectsKey effectKey = new PreEffectsKey(paramID,
2235                                                                 field.toString(), field.getType()
2236                                                                                 .getSafeSymbol(), effectType);
2237                                                 preeffectsSet.add(effectKey);
2238                                         }
2239                                 }
2240
2241                                 // check weather this heap region is parameter
2242                                 // reachable...
2243
2244                                 paramSet = og.idSecondary2paramIndexSet.get(hrn.getID());
2245                                 if (paramSet != null) {
2246                                         Iterator<Integer> paramIter = paramSet.iterator();
2247
2248                                         while (paramIter.hasNext()) {
2249                                                 Integer paramID = paramIter.next();
2250                                                 PreEffectsKey effectKey = new PreEffectsKey(paramID,
2251                                                                 field.toString(), field.getType()
2252                                                                                 .getSafeSymbol(), effectType);
2253                                                 preeffectsSet.add(effectKey);
2254                                         }
2255                                 }
2256
2257                         }
2258                 }
2259         }
2260         
2261   private void codePlansForward( FlatMethod fm ) {
2262     
2263     // start from flat method top, visit every node in
2264     // method exactly once
2265     Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
2266     flatNodesToVisit.add( fm );
2267
2268     Set<FlatNode> visited = new HashSet<FlatNode>();    
2269
2270     while( !flatNodesToVisit.isEmpty() ) {
2271       Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
2272       FlatNode fn = fnItr.next();
2273
2274       flatNodesToVisit.remove( fn );
2275       visited.add( fn );      
2276
2277       Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
2278       assert seseStack != null;      
2279
2280       // use incoming results as "dot statement" or just
2281       // before the current statement
2282       VarSrcTokTable dotSTtable = new VarSrcTokTable();
2283       for( int i = 0; i < fn.numPrev(); i++ ) {
2284         FlatNode nn = fn.getPrev( i );
2285         dotSTtable.merge( variableResults.get( nn ) );
2286       }
2287
2288       // find dt-st notAvailableSet also
2289       Set<TempDescriptor> dotSTnotAvailSet = new HashSet<TempDescriptor>();      
2290       for( int i = 0; i < fn.numPrev(); i++ ) {
2291         FlatNode nn = fn.getPrev( i );       
2292         Set<TempDescriptor> notAvailIn = notAvailableResults.get( nn );
2293         if( notAvailIn != null ) {
2294           dotSTnotAvailSet.addAll( notAvailIn );
2295         }
2296       }
2297
2298       Set<TempDescriptor> dotSTlive = livenessRootView.get( fn );
2299
2300       if( !seseStack.empty() ) {
2301         codePlans_nodeActions( fn, 
2302                                dotSTlive,
2303                                dotSTtable,
2304                                dotSTnotAvailSet,
2305                                seseStack.peek()
2306                                );
2307       }
2308
2309       for( int i = 0; i < fn.numNext(); i++ ) {
2310         FlatNode nn = fn.getNext( i );
2311
2312         if( !visited.contains( nn ) ) {
2313           flatNodesToVisit.add( nn );
2314         }
2315       }
2316     }
2317   }
2318
2319   private void codePlans_nodeActions( FlatNode fn,
2320                                       Set<TempDescriptor> liveSetIn,
2321                                       VarSrcTokTable vstTableIn,
2322                                       Set<TempDescriptor> notAvailSetIn,
2323                                       FlatSESEEnterNode currentSESE ) {
2324     
2325     CodePlan plan = new CodePlan( currentSESE);
2326
2327     switch( fn.kind() ) {
2328
2329     case FKind.FlatSESEEnterNode: {
2330       FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
2331
2332       // track the source types of the in-var set so generated
2333       // code at this SESE issue can compute the number of
2334       // dependencies properly
2335       Iterator<TempDescriptor> inVarItr = fsen.getInVarSet().iterator();
2336       while( inVarItr.hasNext() ) {
2337         TempDescriptor inVar = inVarItr.next();
2338         Integer srcType = 
2339           vstTableIn.getRefVarSrcType( inVar, 
2340                                        fsen,
2341                                        fsen.getParent() );
2342
2343         // the current SESE needs a local space to track the dynamic
2344         // variable and the child needs space in its SESE record
2345         if( srcType.equals( VarSrcTokTable.SrcType_DYNAMIC ) ) {
2346           fsen.addDynamicInVar( inVar );
2347           fsen.getParent().addDynamicVar( inVar );
2348
2349         } else if( srcType.equals( VarSrcTokTable.SrcType_STATIC ) ) {
2350           fsen.addStaticInVar( inVar );
2351           VariableSourceToken vst = vstTableIn.get( inVar ).iterator().next();
2352           fsen.putStaticInVar2src( inVar, vst );
2353           fsen.addStaticInVarSrc( new SESEandAgePair( vst.getSESE(), 
2354                                                       vst.getAge() 
2355                                                     ) 
2356                                 );
2357
2358         } else {
2359           assert srcType.equals( VarSrcTokTable.SrcType_READY );
2360           fsen.addReadyInVar( inVar );
2361         }       
2362       }
2363
2364     } break;
2365
2366     case FKind.FlatSESEExitNode: {
2367       FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
2368     } break;
2369
2370     case FKind.FlatOpNode: {
2371       FlatOpNode fon = (FlatOpNode) fn;
2372
2373       if( fon.getOp().getOp() == Operation.ASSIGN ) {
2374         TempDescriptor lhs = fon.getDest();
2375         TempDescriptor rhs = fon.getLeft();        
2376
2377         // if this is an op node, don't stall, copy
2378         // source and delay until we need to use value
2379
2380         // ask whether lhs and rhs sources are dynamic, static, etc.
2381         Integer lhsSrcType
2382           = vstTableIn.getRefVarSrcType( lhs,
2383                                          currentSESE,
2384                                          currentSESE.getParent() );
2385
2386         Integer rhsSrcType
2387           = vstTableIn.getRefVarSrcType( rhs,
2388                                          currentSESE,
2389                                          currentSESE.getParent() );
2390
2391         if( rhsSrcType.equals( VarSrcTokTable.SrcType_DYNAMIC ) ) {
2392           // if rhs is dynamic going in, lhs will definitely be dynamic
2393           // going out of this node, so track that here   
2394           plan.addDynAssign( lhs, rhs );
2395           currentSESE.addDynamicVar( lhs );
2396           currentSESE.addDynamicVar( rhs );
2397
2398         } else if( lhsSrcType.equals( VarSrcTokTable.SrcType_DYNAMIC ) ) {
2399           // otherwise, if the lhs is dynamic, but the rhs is not, we
2400           // need to update the variable's dynamic source as "current SESE"
2401           plan.addDynAssign( lhs );
2402         }       
2403
2404         // only break if this is an ASSIGN op node,
2405         // otherwise fall through to default case
2406         break;
2407       }
2408     }
2409
2410     // note that FlatOpNode's that aren't ASSIGN
2411     // fall through to this default case
2412     default: {          
2413
2414       // a node with no live set has nothing to stall for
2415       if( liveSetIn == null ) {
2416         break;
2417       }
2418
2419       TempDescriptor[] readarray = fn.readsTemps();
2420       for( int i = 0; i < readarray.length; i++ ) {
2421         TempDescriptor readtmp = readarray[i];
2422
2423         // ignore temps that are definitely available 
2424         // when considering to stall on it
2425         if( !notAvailSetIn.contains( readtmp ) ) {
2426           continue;
2427         }
2428
2429         // check the source type of this variable
2430         Integer srcType 
2431           = vstTableIn.getRefVarSrcType( readtmp,
2432                                          currentSESE,
2433                                          currentSESE.getParent() );
2434
2435         if( srcType.equals( VarSrcTokTable.SrcType_DYNAMIC ) ) {
2436           // 1) It is not clear statically where this variable will
2437           // come from statically, so dynamically we must keep track
2438           // along various control paths, and therefore when we stall,
2439           // just stall for the exact thing we need and move on
2440           plan.addDynamicStall( readtmp );
2441           currentSESE.addDynamicVar( readtmp );  
2442
2443         } else if( srcType.equals( VarSrcTokTable.SrcType_STATIC ) ) {    
2444           // 2) Single token/age pair: Stall for token/age pair, and copy
2445           // all live variables with same token/age pair at the same
2446           // time.  This is the same stuff that the notavaialable analysis 
2447           // marks as now available.      
2448
2449           VariableSourceToken vst = vstTableIn.get( readtmp ).iterator().next();
2450
2451           Iterator<VariableSourceToken> availItr = 
2452             vstTableIn.get( vst.getSESE(), vst.getAge() ).iterator();
2453
2454           while( availItr.hasNext() ) {
2455             VariableSourceToken vstAlsoAvail = availItr.next();
2456
2457             // only grab additional stuff that is live
2458             Set<TempDescriptor> copySet = new HashSet<TempDescriptor>();
2459
2460             Iterator<TempDescriptor> refVarItr = vstAlsoAvail.getRefVars().iterator();
2461             while( refVarItr.hasNext() ) {
2462               TempDescriptor refVar = refVarItr.next();
2463               if( liveSetIn.contains( refVar ) ) {
2464                 copySet.add( refVar );
2465               }
2466             }
2467
2468             if( !copySet.isEmpty() ) {
2469               plan.addStall2CopySet( vstAlsoAvail, copySet );
2470             }
2471           }                      
2472
2473         } else {
2474           // the other case for srcs is READY, so do nothing
2475         }
2476
2477         // assert that everything being stalled for is in the
2478         // "not available" set coming into this flat node and
2479         // that every VST identified is in the possible "stall set"
2480         // that represents VST's from children SESE's
2481
2482       }      
2483     } break;
2484       
2485     } // end switch
2486
2487
2488     // identify sese-age pairs that are statically useful
2489     // and should have an associated SESE variable in code
2490     // JUST GET ALL SESE/AGE NAMES FOR NOW, PRUNE LATER,
2491     // AND ALWAYS GIVE NAMES TO PARENTS
2492     Set<VariableSourceToken> staticSet = vstTableIn.get();
2493     Iterator<VariableSourceToken> vstItr = staticSet.iterator();
2494     while( vstItr.hasNext() ) {
2495       VariableSourceToken vst = vstItr.next();
2496
2497       // placeholder source tokens are useful results, but
2498       // the placeholder static name is never needed
2499       if( vst.getSESE().getIsCallerSESEplaceholder() ) {
2500         continue;
2501       }
2502
2503       FlatSESEEnterNode sese = currentSESE;
2504       while( sese != null ) {
2505         sese.addNeededStaticName( 
2506                                  new SESEandAgePair( vst.getSESE(), vst.getAge() ) 
2507                                   );
2508         sese.mustTrackAtLeastAge( vst.getAge() );
2509         
2510         sese = sese.getParent();
2511       }
2512     }
2513
2514
2515     codePlans.put( fn, plan );
2516
2517
2518     // if any variables at this-node-*dot* have a static source (exactly one vst)
2519     // but go to a dynamic source at next-node-*dot*, create a new IR graph
2520     // node on that edge to track the sources dynamically
2521     VarSrcTokTable thisVstTable = variableResults.get( fn );
2522     for( int i = 0; i < fn.numNext(); i++ ) {
2523       FlatNode            nn           = fn.getNext( i );
2524       VarSrcTokTable      nextVstTable = variableResults.get( nn );
2525       Set<TempDescriptor> nextLiveIn   = livenessRootView.get( nn );
2526
2527       // the table can be null if it is one of the few IR nodes
2528       // completely outside of the root SESE scope
2529       if( nextVstTable != null && nextLiveIn != null ) {
2530
2531         Hashtable<TempDescriptor, VariableSourceToken> static2dynamicSet = 
2532           thisVstTable.getStatic2DynamicSet( nextVstTable, 
2533                                              nextLiveIn,
2534                                              currentSESE,
2535                                              currentSESE.getParent() 
2536                                            );
2537         
2538         if( !static2dynamicSet.isEmpty() ) {
2539
2540           // either add these results to partial fixed-point result
2541           // or make a new one if we haven't made any here yet
2542           FlatEdge fe = new FlatEdge( fn, nn );
2543           FlatWriteDynamicVarNode fwdvn = wdvNodesToSpliceIn.get( fe );
2544
2545           if( fwdvn == null ) {
2546             fwdvn = new FlatWriteDynamicVarNode( fn, 
2547                                                  nn,
2548                                                  static2dynamicSet,
2549                                                  currentSESE
2550                                                  );
2551             wdvNodesToSpliceIn.put( fe, fwdvn );
2552           } else {
2553             fwdvn.addMoreVar2Src( static2dynamicSet );
2554           }
2555         }
2556       }
2557     }
2558   }
2559
2560
2561   public void writeReports( String timeReport ) throws java.io.IOException {
2562
2563     BufferedWriter bw = new BufferedWriter( new FileWriter( "mlpReport_summary.txt" ) );
2564     bw.write( "MLP Analysis Results\n\n" );
2565     bw.write( timeReport+"\n\n" );
2566     printSESEHierarchy( bw );
2567     bw.write( "\n" );
2568     printSESEInfo( bw );
2569     bw.close();
2570
2571     Iterator<Descriptor> methItr = ownAnalysis.descriptorsToAnalyze.iterator();
2572     while( methItr.hasNext() ) {
2573       MethodDescriptor md = (MethodDescriptor) methItr.next();      
2574       FlatMethod       fm = state.getMethodFlat( md );
2575       bw = new BufferedWriter( new FileWriter( "mlpReport_"+
2576                                                md.getClassMethodName()+
2577                                                md.getSafeMethodDescriptor()+
2578                                                ".txt" ) );
2579       bw.write( "MLP Results for "+md+"\n-------------------\n");
2580       bw.write( "\n\nLive-In, Root View\n------------------\n"          +fm.printMethod( livenessRootView ) );
2581       bw.write( "\n\nVariable Results-Out\n----------------\n"          +fm.printMethod( variableResults ) );
2582       bw.write( "\n\nNot Available Results-Out\n---------------------\n"+fm.printMethod( notAvailableResults ) );
2583       bw.write( "\n\nCode Plans\n----------\n"                          +fm.printMethod( codePlans ) );
2584       bw.write("\n\nSESE Effects\n----------------------\n"+printSESEEffects());
2585       bw.close();
2586     }
2587   }
2588   
2589         private String printSESEEffects() {
2590
2591                 StringWriter writer = new StringWriter();
2592
2593                 Iterator<FlatSESEEnterNode> keyIter = allSESEs.iterator();
2594
2595                 while (keyIter.hasNext()) {
2596                         FlatSESEEnterNode seseEnter = keyIter.next();
2597                         String result = seseEnter.getSeseEffectsSet().printSet();
2598                         if (result.length() > 0) {
2599                                 writer.write("\nSESE " + seseEnter + "\n");
2600                                 writer.write(result);
2601                         }
2602                 }
2603                 keyIter = rootSESEs.iterator();
2604                 while (keyIter.hasNext()) {
2605                         FlatSESEEnterNode seseEnter = keyIter.next();
2606                         if (seseEnter.getIsCallerSESEplaceholder()) {
2607                                 if (!seseEnter.getChildren().isEmpty()) {
2608                                         String result = seseEnter.getSeseEffectsSet().printSet();
2609                                         if (result.length() > 0) {
2610                                                 writer.write("\nSESE " + seseEnter + "\n");
2611                                                 writer.write(result);
2612                                         }
2613                                 }
2614                         }
2615                 }
2616
2617                 return writer.toString();
2618
2619         }
2620
2621   private void printSESEHierarchy( BufferedWriter bw ) throws java.io.IOException {
2622     bw.write( "SESE Hierarchy\n--------------\n" ); 
2623     Iterator<FlatSESEEnterNode> rootItr = rootSESEs.iterator();
2624     while( rootItr.hasNext() ) {
2625       FlatSESEEnterNode root = rootItr.next();
2626       if( root.getIsCallerSESEplaceholder() ) {
2627         if( !root.getChildren().isEmpty() ) {
2628           printSESEHierarchyTree( bw, root, 0 );
2629         }
2630       } else {
2631         printSESEHierarchyTree( bw, root, 0 );
2632       }
2633     }
2634   }
2635
2636   private void printSESEHierarchyTree( BufferedWriter bw,
2637                                        FlatSESEEnterNode fsen,
2638                                        int depth 
2639                                      ) throws java.io.IOException {
2640     for( int i = 0; i < depth; ++i ) {
2641       bw.write( "  " );
2642     }
2643     bw.write( "- "+fsen.getPrettyIdentifier()+"\n" );
2644
2645     Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
2646     while( childItr.hasNext() ) {
2647       FlatSESEEnterNode fsenChild = childItr.next();
2648       printSESEHierarchyTree( bw, fsenChild, depth + 1 );
2649     }
2650   }
2651
2652   
2653   private void printSESEInfo( BufferedWriter bw ) throws java.io.IOException {
2654     bw.write("\nSESE info\n-------------\n" ); 
2655     Iterator<FlatSESEEnterNode> rootItr = rootSESEs.iterator();
2656     while( rootItr.hasNext() ) {
2657       FlatSESEEnterNode root = rootItr.next();
2658       if( root.getIsCallerSESEplaceholder() ) {
2659         if( !root.getChildren().isEmpty() ) {
2660           printSESEInfoTree( bw, root );
2661         }
2662       } else {
2663         printSESEInfoTree( bw, root );
2664       }
2665     }
2666   }
2667
2668   private void printSESEInfoTree( BufferedWriter bw,
2669                                   FlatSESEEnterNode fsen 
2670                                 ) throws java.io.IOException {
2671
2672     if( !fsen.getIsCallerSESEplaceholder() ) {
2673       bw.write( "SESE "+fsen.getPrettyIdentifier()+" {\n" );
2674
2675       bw.write( "  in-set: "+fsen.getInVarSet()+"\n" );
2676       Iterator<TempDescriptor> tItr = fsen.getInVarSet().iterator();
2677       while( tItr.hasNext() ) {
2678         TempDescriptor inVar = tItr.next();
2679    &nb