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