3 import java.io.BufferedWriter;
4 import java.io.FileWriter;
5 import java.io.IOException;
6 import java.io.StringWriter;
7 import java.util.Enumeration;
8 import java.util.HashSet;
9 import java.util.Hashtable;
10 import java.util.Iterator;
11 import java.util.LinkedList;
14 import java.util.Stack;
15 import java.util.Map.Entry;
16 import Analysis.CallGraph.CallGraph;
17 import Analysis.CallGraph.JavaCallGraph;
18 import Analysis.OwnershipAnalysis.AllocationSite;
19 import Analysis.OwnershipAnalysis.EffectsKey;
20 import Analysis.OwnershipAnalysis.HeapRegionNode;
21 import Analysis.OwnershipAnalysis.LabelNode;
22 import Analysis.OwnershipAnalysis.MethodContext;
23 import Analysis.OwnershipAnalysis.MethodEffects;
24 import Analysis.OwnershipAnalysis.OwnershipAnalysis;
25 import Analysis.OwnershipAnalysis.OwnershipGraph;
26 import Analysis.OwnershipAnalysis.OwnershipNode;
27 import Analysis.OwnershipAnalysis.ParameterDecomposition;
28 import Analysis.OwnershipAnalysis.ReachabilitySet;
29 import Analysis.OwnershipAnalysis.ReferenceEdge;
30 import Analysis.OwnershipAnalysis.TokenTuple;
31 import Analysis.OwnershipAnalysis.TokenTupleSet;
33 import IR.FieldDescriptor;
34 import IR.MethodDescriptor;
39 import IR.Flat.FlatCall;
40 import IR.Flat.FlatCondBranch;
41 import IR.Flat.FlatEdge;
42 import IR.Flat.FlatElementNode;
43 import IR.Flat.FlatFieldNode;
44 import IR.Flat.FlatLiteralNode;
45 import IR.Flat.FlatMethod;
46 import IR.Flat.FlatNew;
47 import IR.Flat.FlatNode;
48 import IR.Flat.FlatOpNode;
49 import IR.Flat.FlatReturnNode;
50 import IR.Flat.FlatSESEEnterNode;
51 import IR.Flat.FlatSESEExitNode;
52 import IR.Flat.FlatSetElementNode;
53 import IR.Flat.FlatSetFieldNode;
54 import IR.Flat.FlatWriteDynamicVarNode;
55 import IR.Flat.TempDescriptor;
58 public class MLPAnalysis {
60 // data from the compiler
62 private TypeUtil typeUtil;
63 private CallGraph callGraph;
64 private OwnershipAnalysis ownAnalysis;
67 // an implicit SESE is automatically spliced into
68 // the IR graph around the C main before this analysis--it
69 // is nothing special except that we can make assumptions
70 // about it, such as the whole program ends when it ends
71 private FlatSESEEnterNode mainSESE;
73 // SESEs that are the root of an SESE tree belong to this
74 // set--the main SESE is always a root, statically SESEs
75 // inside methods are a root because we don't know how they
76 // will fit into the runtime tree of SESEs
77 private Set<FlatSESEEnterNode> rootSESEs;
79 // simply a set of every reachable SESE in the program, not
80 // including caller placeholder SESEs
81 private Set<FlatSESEEnterNode> allSESEs;
84 // A mapping of flat nodes to the stack of SESEs for that node, where
85 // an SESE is the child of the SESE directly below it on the stack.
86 // These stacks do not reflect the heirarchy over methods calls--whenever
87 // there is an empty stack it means all variables are available.
88 private Hashtable< FlatNode, Stack<FlatSESEEnterNode> > seseStacks;
90 private Hashtable< FlatNode, Set<TempDescriptor> > livenessRootView;
91 private Hashtable< FlatNode, Set<TempDescriptor> > livenessVirtualReads;
92 private Hashtable< FlatNode, VarSrcTokTable > variableResults;
93 private Hashtable< FlatNode, Set<TempDescriptor> > notAvailableResults;
94 private Hashtable< FlatNode, CodePlan > codePlans;
96 private Hashtable< FlatSESEEnterNode, Set<TempDescriptor> > notAvailableIntoSESE;
98 private Hashtable< FlatEdge, FlatWriteDynamicVarNode > wdvNodesToSpliceIn;
100 private Hashtable< MethodContext, HashSet<AllocationSite>> mapMethodContextToLiveInAllocationSiteSet;
102 private Hashtable < FlatNode, ParentChildConflictsMap > conflictsResults;
103 private Hashtable< FlatMethod, MethodSummary > methodSummaryResults;
104 private OwnershipAnalysis ownAnalysisForSESEConflicts;
105 private Hashtable <FlatNode, ConflictGraph> conflictGraphResults;
107 // temporal data structures to track analysis progress.
108 private MethodSummary currentMethodSummary;
109 private HashSet<PreEffectsKey> preeffectsSet;
110 private Hashtable<FlatNode, Boolean> isAfterChildSESEIndicatorMap;
111 private Hashtable<FlatNode, SESESummary> seseSummaryMap;
112 private Hashtable<ConflictGraph, HashSet<SESELock>> conflictGraphLockMap;
114 public static int maxSESEage = -1;
117 // use these methods in BuildCode to have access to analysis results
118 public FlatSESEEnterNode getMainSESE() {
122 public Set<FlatSESEEnterNode> getRootSESEs() {
126 public Set<FlatSESEEnterNode> getAllSESEs() {
130 public int getMaxSESEage() {
135 public CodePlan getCodePlan( FlatNode fn ) {
136 CodePlan cp = codePlans.get( fn );
141 public MLPAnalysis( State state,
144 OwnershipAnalysis ownAnalysis
147 double timeStartAnalysis = (double) System.nanoTime();
151 this.callGraph = callGraph;
152 this.ownAnalysis = ownAnalysis;
153 this.maxSESEage = state.MLP_MAXSESEAGE;
155 rootSESEs = new HashSet<FlatSESEEnterNode>();
156 allSESEs = new HashSet<FlatSESEEnterNode>();
158 seseStacks = new Hashtable< FlatNode, Stack<FlatSESEEnterNode> >();
159 livenessRootView = new Hashtable< FlatNode, Set<TempDescriptor> >();
160 livenessVirtualReads = new Hashtable< FlatNode, Set<TempDescriptor> >();
161 variableResults = new Hashtable< FlatNode, VarSrcTokTable >();
162 notAvailableResults = new Hashtable< FlatNode, Set<TempDescriptor> >();
163 codePlans = new Hashtable< FlatNode, CodePlan >();
164 wdvNodesToSpliceIn = new Hashtable< FlatEdge, FlatWriteDynamicVarNode >();
166 notAvailableIntoSESE = new Hashtable< FlatSESEEnterNode, Set<TempDescriptor> >();
168 mapMethodContextToLiveInAllocationSiteSet = new Hashtable< MethodContext, HashSet<AllocationSite>>();
170 conflictsResults = new Hashtable < FlatNode, ParentChildConflictsMap >();
171 methodSummaryResults=new Hashtable<FlatMethod, MethodSummary>();
172 conflictGraphResults=new Hashtable<FlatNode, ConflictGraph>();
174 seseSummaryMap= new Hashtable<FlatNode, SESESummary>();
175 isAfterChildSESEIndicatorMap= new Hashtable<FlatNode, Boolean>();
176 conflictGraphLockMap=new Hashtable<ConflictGraph, HashSet<SESELock>>();
178 FlatMethod fmMain = state.getMethodFlat( typeUtil.getMain() );
180 mainSESE = (FlatSESEEnterNode) fmMain.getNext(0);
181 mainSESE.setfmEnclosing( fmMain );
182 mainSESE.setmdEnclosing( fmMain.getMethod() );
183 mainSESE.setcdEnclosing( fmMain.getMethod().getClassDesc() );
187 // run analysis on each method that is actually called
188 // reachability analysis already computed this so reuse
189 Iterator<Descriptor> methItr = ownAnalysis.descriptorsToAnalyze.iterator();
190 while( methItr.hasNext() ) {
191 Descriptor d = methItr.next();
192 FlatMethod fm = state.getMethodFlat( d );
194 // find every SESE from methods that may be called
195 // and organize them into roots and children
196 buildForestForward( fm );
200 // 2nd pass, results are saved in FlatSESEEnterNode, so
201 // intermediate results, for safety, are discarded
202 Iterator<FlatSESEEnterNode> rootItr = rootSESEs.iterator();
203 while( rootItr.hasNext() ) {
204 FlatSESEEnterNode root = rootItr.next();
205 livenessAnalysisBackward( root,
212 methItr = ownAnalysis.descriptorsToAnalyze.iterator();
213 while( methItr.hasNext() ) {
214 Descriptor d = methItr.next();
215 FlatMethod fm = state.getMethodFlat( d );
217 // starting from roots do a forward, fixed-point
218 // variable analysis for refinement and stalls
219 variableAnalysisForward( fm );
222 // 4th pass, compute liveness contribution from
223 // virtual reads discovered in variable pass
224 rootItr = rootSESEs.iterator();
225 while( rootItr.hasNext() ) {
226 FlatSESEEnterNode root = rootItr.next();
227 livenessAnalysisBackward( root,
234 SOMETHING IS WRONG WITH THIS, DON'T USE IT UNTIL IT CAN BE FIXED
237 methItr = ownAnalysis.descriptorsToAnalyze.iterator();
238 while( methItr.hasNext() ) {
239 Descriptor d = methItr.next();
240 FlatMethod fm = state.getMethodFlat( d );
242 // prune variable results in one traversal
243 // by removing reference variables that are not live
244 pruneVariableResultsWithLiveness( fm );
250 methItr = ownAnalysis.descriptorsToAnalyze.iterator();
251 while( methItr.hasNext() ) {
252 Descriptor d = methItr.next();
253 FlatMethod fm = state.getMethodFlat( d );
255 // compute what is not available at every program
256 // point, in a forward fixed-point pass
257 notAvailableForward( fm );
260 if(state.METHODEFFECTS){
261 // new pass, sese effects analysis
262 methItr = ownAnalysis.descriptorsToAnalyze.iterator();
263 JavaCallGraph javaCallGraph = new JavaCallGraph(state,tu);
264 while( methItr.hasNext() ) {
265 Descriptor d = methItr.next();
266 FlatMethod fm = state.getMethodFlat( d );
267 methodEffects(fm,javaCallGraph);
270 // Parent/child memory conflicts analysis
271 seseConflictsForward(javaCallGraph);
273 Set<MethodContext> keySet=mapMethodContextToLiveInAllocationSiteSet.keySet();
274 for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
275 MethodContext methodContext = (MethodContext) iterator.next();
276 HashSet<AllocationSite> asSet=mapMethodContextToLiveInAllocationSiteSet.get(methodContext);
277 for (Iterator iterator2 = asSet.iterator(); iterator2.hasNext();) {
278 AllocationSite allocationSite = (AllocationSite) iterator2.next();
282 // disjoint analysis with a set of flagged allocation sites of live-in variables & stall sites
284 ownAnalysisForSESEConflicts = new OwnershipAnalysis(state,
287 ownAnalysis.liveness,
288 ownAnalysis.arrayReferencees,
289 state.OWNERSHIPALLOCDEPTH, false,
290 false, state.OWNERSHIPALIASFILE,
292 mapMethodContextToLiveInAllocationSiteSet);
294 methItr = ownAnalysisForSESEConflicts.descriptorsToAnalyze.iterator();
295 while (methItr.hasNext()) {
296 Descriptor d = methItr.next();
297 FlatMethod fm = state.getMethodFlat(d);
298 debugFunction(ownAnalysisForSESEConflicts, fm);
301 } catch (IOException e) {
302 System.err.println(e);
305 // postSESEConflictsForward(javaCallGraph);
306 // another pass for making graph
312 methItr = ownAnalysis.descriptorsToAnalyze.iterator();
313 while (methItr.hasNext()) {
314 Descriptor d = methItr.next();
315 FlatMethod fm = state.getMethodFlat(d);
316 makeConflictGraph2(fm);
319 Enumeration<FlatNode> keyEnum1=conflictGraphResults.keys();
320 while (keyEnum1.hasMoreElements()) {
321 FlatNode flatNode = (FlatNode) keyEnum1.nextElement();
322 ConflictGraph conflictGraph=conflictGraphResults.get(flatNode);
323 conflictGraph.analyzeConflicts();
324 conflictGraphResults.put(flatNode, conflictGraph);
328 Enumeration<FlatNode> keyEnum=conflictGraphResults.keys();
329 while (keyEnum.hasMoreElements()) {
330 FlatNode key = (FlatNode) keyEnum.nextElement();
331 ConflictGraph cg=conflictGraphResults.get(key);
333 cg.writeGraph("ConflictGraphFor"+key, false);
334 } catch (IOException e) {
335 System.out.println("Error writing");
344 methItr = ownAnalysis.descriptorsToAnalyze.iterator();
345 while( methItr.hasNext() ) {
346 Descriptor d = methItr.next();
347 FlatMethod fm = state.getMethodFlat( d );
349 // compute a plan for code injections
350 codePlansForward( fm );
354 // splice new IR nodes into graph after all
355 // analysis passes are complete
356 Iterator spliceItr = wdvNodesToSpliceIn.entrySet().iterator();
357 while( spliceItr.hasNext() ) {
358 Map.Entry me = (Map.Entry) spliceItr.next();
359 FlatWriteDynamicVarNode fwdvn = (FlatWriteDynamicVarNode) me.getValue();
360 fwdvn.spliceIntoIR();
364 double timeEndAnalysis = (double) System.nanoTime();
365 double dt = (timeEndAnalysis - timeStartAnalysis)/(Math.pow( 10.0, 9.0 ) );
366 String treport = String.format( "The mlp analysis took %.3f sec.", dt );
367 System.out.println( treport );
369 if( state.MLPDEBUG ) {
371 writeReports( treport );
372 } catch( IOException e ) {}
377 private void buildForestForward( FlatMethod fm ) {
379 // start from flat method top, visit every node in
380 // method exactly once, find SESEs and remember
381 // roots and child relationships
382 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
383 flatNodesToVisit.add( fm );
385 Set<FlatNode> visited = new HashSet<FlatNode>();
387 Stack<FlatSESEEnterNode> seseStackFirst = new Stack<FlatSESEEnterNode>();
388 seseStacks.put( fm, seseStackFirst );
390 while( !flatNodesToVisit.isEmpty() ) {
391 Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
392 FlatNode fn = fnItr.next();
394 Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
395 assert seseStack != null;
397 flatNodesToVisit.remove( fn );
400 buildForest_nodeActions( fn, seseStack, fm );
402 for( int i = 0; i < fn.numNext(); i++ ) {
403 FlatNode nn = fn.getNext( i );
405 if( !visited.contains( nn ) ) {
406 flatNodesToVisit.add( nn );
408 // clone stack and send along each analysis path
409 seseStacks.put( nn, (Stack<FlatSESEEnterNode>)seseStack.clone() );
415 private void buildForest_nodeActions( FlatNode fn,
416 Stack<FlatSESEEnterNode> seseStack,
418 switch( fn.kind() ) {
420 case FKind.FlatSESEEnterNode: {
421 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
423 if( !fsen.getIsCallerSESEplaceholder() ) {
424 allSESEs.add( fsen );
427 fsen.setfmEnclosing( fm );
428 fsen.setmdEnclosing( fm.getMethod() );
429 fsen.setcdEnclosing( fm.getMethod().getClassDesc() );
431 if( seseStack.empty() ) {
432 rootSESEs.add( fsen );
433 fsen.setParent( null );
435 seseStack.peek().addChild( fsen );
436 fsen.setParent( seseStack.peek() );
439 seseStack.push( fsen );
442 case FKind.FlatSESEExitNode: {
443 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
444 assert !seseStack.empty();
445 FlatSESEEnterNode fsen = seseStack.pop();
448 case FKind.FlatReturnNode: {
449 FlatReturnNode frn = (FlatReturnNode) fn;
450 if( !seseStack.empty() &&
451 !seseStack.peek().getIsCallerSESEplaceholder()
453 throw new Error( "Error: return statement enclosed within SESE "+
454 seseStack.peek().getPrettyIdentifier() );
462 private void livenessAnalysisBackward( FlatSESEEnterNode fsen,
464 Hashtable< FlatSESEExitNode, Set<TempDescriptor> > liveout ) {
466 // start from an SESE exit, visit nodes in reverse up to
467 // SESE enter in a fixed-point scheme, where children SESEs
468 // should already be analyzed and therefore can be skipped
469 // because child SESE enter node has all necessary info
470 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
473 flatNodesToVisit.add( fsen.getfmEnclosing().getFlatExit() );
475 flatNodesToVisit.add( fsen.getFlatExit() );
478 Hashtable<FlatNode, Set<TempDescriptor>> livenessResults =
479 new Hashtable< FlatNode, Set<TempDescriptor> >();
482 liveout = new Hashtable< FlatSESEExitNode, Set<TempDescriptor> >();
485 while( !flatNodesToVisit.isEmpty() ) {
486 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
487 flatNodesToVisit.remove( fn );
489 Set<TempDescriptor> prev = livenessResults.get( fn );
491 // merge sets from control flow joins
492 Set<TempDescriptor> u = new HashSet<TempDescriptor>();
493 for( int i = 0; i < fn.numNext(); i++ ) {
494 FlatNode nn = fn.getNext( i );
495 Set<TempDescriptor> s = livenessResults.get( nn );
501 Set<TempDescriptor> curr = liveness_nodeActions( fn, u, fsen, toplevel, liveout);
503 // if a new result, schedule backward nodes for analysis
504 if( !curr.equals( prev ) ) {
505 livenessResults.put( fn, curr );
507 // don't flow backwards past current SESE enter
508 if( !fn.equals( fsen ) ) {
509 for( int i = 0; i < fn.numPrev(); i++ ) {
510 FlatNode nn = fn.getPrev( i );
511 flatNodesToVisit.add( nn );
517 Set<TempDescriptor> s = livenessResults.get( fsen );
519 fsen.addInVarSet( s );
522 // remember liveness per node from the root view as the
523 // global liveness of variables for later passes to use
525 livenessRootView.putAll( livenessResults );
528 // post-order traversal, so do children first
529 Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
530 while( childItr.hasNext() ) {
531 FlatSESEEnterNode fsenChild = childItr.next();
532 livenessAnalysisBackward( fsenChild, false, liveout );
536 private Set<TempDescriptor> liveness_nodeActions( FlatNode fn,
537 Set<TempDescriptor> liveIn,
538 FlatSESEEnterNode currentSESE,
540 Hashtable< FlatSESEExitNode, Set<TempDescriptor> > liveout
542 switch( fn.kind() ) {
544 case FKind.FlatSESEExitNode:
546 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
547 if( !liveout.containsKey( fsexn ) ) {
548 liveout.put( fsexn, new HashSet<TempDescriptor>() );
550 liveout.get( fsexn ).addAll( liveIn );
552 // no break, sese exits should also execute default actions
555 // handle effects of statement in reverse, writes then reads
556 TempDescriptor [] writeTemps = fn.writesTemps();
557 for( int i = 0; i < writeTemps.length; ++i ) {
558 liveIn.remove( writeTemps[i] );
561 FlatSESEExitNode fsexn = currentSESE.getFlatExit();
562 Set<TempDescriptor> livetemps = liveout.get( fsexn );
563 if( livetemps != null &&
564 livetemps.contains( writeTemps[i] ) ) {
565 // write to a live out temp...
566 // need to put in SESE liveout set
567 currentSESE.addOutVar( writeTemps[i] );
572 TempDescriptor [] readTemps = fn.readsTemps();
573 for( int i = 0; i < readTemps.length; ++i ) {
574 liveIn.add( readTemps[i] );
577 Set<TempDescriptor> virtualReadTemps = livenessVirtualReads.get( fn );
578 if( virtualReadTemps != null ) {
579 liveIn.addAll( virtualReadTemps );
590 private void variableAnalysisForward( FlatMethod fm ) {
592 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
593 flatNodesToVisit.add( fm );
595 while( !flatNodesToVisit.isEmpty() ) {
596 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
597 flatNodesToVisit.remove( fn );
599 Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
600 assert seseStack != null;
602 VarSrcTokTable prev = variableResults.get( fn );
604 // merge sets from control flow joins
605 VarSrcTokTable curr = new VarSrcTokTable();
606 for( int i = 0; i < fn.numPrev(); i++ ) {
607 FlatNode nn = fn.getPrev( i );
608 VarSrcTokTable incoming = variableResults.get( nn );
609 curr.merge( incoming );
612 if( !seseStack.empty() ) {
613 variable_nodeActions( fn, curr, seseStack.peek() );
616 // if a new result, schedule forward nodes for analysis
617 if( !curr.equals( prev ) ) {
618 variableResults.put( fn, curr );
620 for( int i = 0; i < fn.numNext(); i++ ) {
621 FlatNode nn = fn.getNext( i );
622 flatNodesToVisit.add( nn );
628 private void variable_nodeActions( FlatNode fn,
629 VarSrcTokTable vstTable,
630 FlatSESEEnterNode currentSESE ) {
631 switch( fn.kind() ) {
633 case FKind.FlatSESEEnterNode: {
634 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
635 assert fsen.equals( currentSESE );
637 vstTable.age( currentSESE );
638 vstTable.assertConsistency();
641 case FKind.FlatSESEExitNode: {
642 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
643 FlatSESEEnterNode fsen = fsexn.getFlatEnter();
644 assert currentSESE.getChildren().contains( fsen );
646 // remap all of this child's children tokens to be
647 // from this child as the child exits
648 vstTable.remapChildTokens( fsen );
650 // liveness virtual reads are things that might be
651 // written by an SESE and should be added to the in-set
652 // anything virtually read by this SESE should be pruned
653 // of parent or sibling sources
654 Set<TempDescriptor> liveVars = livenessRootView.get( fn );
655 Set<TempDescriptor> fsenVirtReads = vstTable.calcVirtReadsAndPruneParentAndSiblingTokens( fsen, liveVars );
656 Set<TempDescriptor> fsenVirtReadsOld = livenessVirtualReads.get( fn );
657 if( fsenVirtReadsOld != null ) {
658 fsenVirtReads.addAll( fsenVirtReadsOld );
660 livenessVirtualReads.put( fn, fsenVirtReads );
663 // then all child out-set tokens are guaranteed
664 // to be filled in, so clobber those entries with
665 // the latest, clean sources
666 Iterator<TempDescriptor> outVarItr = fsen.getOutVarSet().iterator();
667 while( outVarItr.hasNext() ) {
668 TempDescriptor outVar = outVarItr.next();
669 HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
671 VariableSourceToken vst =
672 new VariableSourceToken( ts,
677 vstTable.remove( outVar );
680 vstTable.assertConsistency();
684 case FKind.FlatOpNode: {
685 FlatOpNode fon = (FlatOpNode) fn;
687 if( fon.getOp().getOp() == Operation.ASSIGN ) {
688 TempDescriptor lhs = fon.getDest();
689 TempDescriptor rhs = fon.getLeft();
691 vstTable.remove( lhs );
693 Set<VariableSourceToken> forAddition = new HashSet<VariableSourceToken>();
695 Iterator<VariableSourceToken> itr = vstTable.get( rhs ).iterator();
696 while( itr.hasNext() ) {
697 VariableSourceToken vst = itr.next();
699 HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
702 if( currentSESE.getChildren().contains( vst.getSESE() ) ) {
703 // if the source comes from a child, copy it over
704 forAddition.add( new VariableSourceToken( ts,
711 // otherwise, stamp it as us as the source
712 forAddition.add( new VariableSourceToken( ts,
721 vstTable.addAll( forAddition );
723 // only break if this is an ASSIGN op node,
724 // otherwise fall through to default case
725 vstTable.assertConsistency();
730 // note that FlatOpNode's that aren't ASSIGN
731 // fall through to this default case
733 TempDescriptor [] writeTemps = fn.writesTemps();
734 if( writeTemps.length > 0 ) {
737 // for now, when writeTemps > 1, make sure
738 // its a call node, programmer enforce only
739 // doing stuff like calling a print routine
740 //assert writeTemps.length == 1;
741 if( writeTemps.length > 1 ) {
742 assert fn.kind() == FKind.FlatCall ||
743 fn.kind() == FKind.FlatMethod;
747 vstTable.remove( writeTemps[0] );
749 HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
750 ts.add( writeTemps[0] );
752 vstTable.add( new VariableSourceToken( ts,
760 vstTable.assertConsistency();
767 private void pruneVariableResultsWithLiveness( FlatMethod fm ) {
769 // start from flat method top, visit every node in
770 // method exactly once
771 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
772 flatNodesToVisit.add( fm );
774 Set<FlatNode> visited = new HashSet<FlatNode>();
776 while( !flatNodesToVisit.isEmpty() ) {
777 Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
778 FlatNode fn = fnItr.next();
780 flatNodesToVisit.remove( fn );
783 Set<TempDescriptor> rootLiveSet = livenessRootView.get( fn );
784 VarSrcTokTable vstTable = variableResults.get( fn );
786 vstTable.pruneByLiveness( rootLiveSet );
788 for( int i = 0; i < fn.numNext(); i++ ) {
789 FlatNode nn = fn.getNext( i );
791 if( !visited.contains( nn ) ) {
792 flatNodesToVisit.add( nn );
799 private void notAvailableForward( FlatMethod fm ) {
801 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
802 flatNodesToVisit.add( fm );
804 while( !flatNodesToVisit.isEmpty() ) {
805 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
806 flatNodesToVisit.remove( fn );
808 Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
809 assert seseStack != null;
811 Set<TempDescriptor> prev = notAvailableResults.get( fn );
813 Set<TempDescriptor> curr = new HashSet<TempDescriptor>();
814 for( int i = 0; i < fn.numPrev(); i++ ) {
815 FlatNode nn = fn.getPrev( i );
816 Set<TempDescriptor> notAvailIn = notAvailableResults.get( nn );
817 if( notAvailIn != null ) {
818 curr.addAll( notAvailIn );
822 if( !seseStack.empty() ) {
823 notAvailable_nodeActions( fn, curr, seseStack.peek() );
826 // if a new result, schedule forward nodes for analysis
827 if( !curr.equals( prev ) ) {
828 notAvailableResults.put( fn, curr );
830 for( int i = 0; i < fn.numNext(); i++ ) {
831 FlatNode nn = fn.getNext( i );
832 flatNodesToVisit.add( nn );
838 private void notAvailable_nodeActions( FlatNode fn,
839 Set<TempDescriptor> notAvailSet,
840 FlatSESEEnterNode currentSESE ) {
842 // any temps that are removed from the not available set
843 // at this node should be marked in this node's code plan
844 // as temps to be grabbed at runtime!
846 switch( fn.kind() ) {
848 case FKind.FlatSESEEnterNode: {
849 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
850 assert fsen.equals( currentSESE );
852 // keep a copy of what's not available into the SESE
853 // and restore it at the matching exit node
854 Set<TempDescriptor> notAvailCopy = new HashSet<TempDescriptor>();
855 Iterator<TempDescriptor> tdItr = notAvailSet.iterator();
856 while( tdItr.hasNext() ) {
857 notAvailCopy.add( tdItr.next() );
859 notAvailableIntoSESE.put( fsen, notAvailCopy );
864 case FKind.FlatSESEExitNode: {
865 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
866 FlatSESEEnterNode fsen = fsexn.getFlatEnter();
867 assert currentSESE.getChildren().contains( fsen );
869 notAvailSet.addAll( fsen.getOutVarSet() );
871 Set<TempDescriptor> notAvailIn = notAvailableIntoSESE.get( fsen );
872 assert notAvailIn != null;
873 notAvailSet.addAll( notAvailIn );
877 case FKind.FlatMethod: {
881 case FKind.FlatOpNode: {
882 FlatOpNode fon = (FlatOpNode) fn;
884 if( fon.getOp().getOp() == Operation.ASSIGN ) {
885 TempDescriptor lhs = fon.getDest();
886 TempDescriptor rhs = fon.getLeft();
888 // copy makes lhs same availability as rhs
889 if( notAvailSet.contains( rhs ) ) {
890 notAvailSet.add( lhs );
892 notAvailSet.remove( lhs );
895 // only break if this is an ASSIGN op node,
896 // otherwise fall through to default case
901 // note that FlatOpNode's that aren't ASSIGN
902 // fall through to this default case
904 TempDescriptor [] writeTemps = fn.writesTemps();
905 for( int i = 0; i < writeTemps.length; i++ ) {
906 TempDescriptor wTemp = writeTemps[i];
907 notAvailSet.remove( wTemp );
909 TempDescriptor [] readTemps = fn.readsTemps();
910 for( int i = 0; i < readTemps.length; i++ ) {
911 TempDescriptor rTemp = readTemps[i];
912 notAvailSet.remove( rTemp );
914 // if this variable has exactly one source, potentially
915 // get other things from this source as well
916 VarSrcTokTable vstTable = variableResults.get( fn );
918 VSTWrapper vstIfStatic = new VSTWrapper();
920 vstTable.getRefVarSrcType( rTemp,
925 if( srcType.equals( VarSrcTokTable.SrcType_STATIC ) ) {
927 VariableSourceToken vst = vstIfStatic.vst;
929 Iterator<VariableSourceToken> availItr = vstTable.get( vst.getSESE(),
933 // look through things that are also available from same source
934 while( availItr.hasNext() ) {
935 VariableSourceToken vstAlsoAvail = availItr.next();
937 Iterator<TempDescriptor> refVarItr = vstAlsoAvail.getRefVars().iterator();
938 while( refVarItr.hasNext() ) {
939 TempDescriptor refVarAlso = refVarItr.next();
941 // if a variable is available from the same source, AND it ALSO
942 // only comes from one statically known source, mark it available
943 VSTWrapper vstIfStaticNotUsed = new VSTWrapper();
944 Integer srcTypeAlso =
945 vstTable.getRefVarSrcType( refVarAlso,
949 if( srcTypeAlso.equals( VarSrcTokTable.SrcType_STATIC ) ) {
950 notAvailSet.remove( refVarAlso );
961 private void debugFunction(OwnershipAnalysis oa2, FlatMethod fm) {
963 String methodName="SomeWork";
965 MethodDescriptor md=fm.getMethod();
966 HashSet<MethodContext> mcSet=oa2.getAllMethodContextSetByDescriptor(md);
967 Iterator<MethodContext> mcIter=mcSet.iterator();
969 while(mcIter.hasNext()){
970 MethodContext mc=mcIter.next();
972 OwnershipGraph og=oa2.getOwnvershipGraphByMethodContext(mc);
974 if(fm.toString().indexOf(methodName)>0){
976 og.writeGraph("SECONDGRAPH"+fm.toString(),
977 true, // write labels (variables)
978 true, // selectively hide intermediate temp vars
979 true, // prune unreachable heap regions
980 false, // show back edges to confirm graph validity
981 false, // show parameter indices (unmaintained!)
982 true, // hide subset reachability states
983 false);// hide edge taints
984 } catch (IOException e) {
985 System.out.println("Error writing debug capture.");
993 private void methodEffects(FlatMethod fm, CallGraph callGraph) {
995 MethodDescriptor md=fm.getMethod();
996 HashSet<MethodContext> mcSet=ownAnalysis.getAllMethodContextSetByDescriptor(md);
997 Iterator<MethodContext> mcIter=mcSet.iterator();
999 while(mcIter.hasNext()){
1000 MethodContext mc=mcIter.next();
1002 Set<FlatNode> visited = new HashSet<FlatNode>();
1004 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
1005 flatNodesToVisit.add(fm);
1007 Hashtable<TempDescriptor, TempDescriptor> invarMap=new Hashtable<TempDescriptor,TempDescriptor>();
1009 while (!flatNodesToVisit.isEmpty()) {
1010 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
1011 flatNodesToVisit.remove(fn);
1013 Stack<FlatSESEEnterNode> seseStack = seseStacks.get(fn);
1014 assert seseStack != null;
1016 if (!seseStack.empty()) {
1017 effects_nodeActions(mc, fn, seseStack.peek(), callGraph,invarMap);
1020 flatNodesToVisit.remove(fn);
1023 for (int i = 0; i < fn.numNext(); i++) {
1024 FlatNode nn = fn.getNext(i);
1025 if (!visited.contains(nn)) {
1026 flatNodesToVisit.add(nn);
1037 private void analyzeRelatedAllocationSite(MethodDescriptor callerMD,
1038 MethodContext calleeMC, HashSet<Integer> paramIndexSet,
1039 HashSet<HeapRegionNode> visitedHRN) {
1041 HashSet<MethodContext> mcSet = ownAnalysis
1042 .getAllMethodContextSetByDescriptor(callerMD);
1044 if (mcSet != null) {
1046 Iterator<MethodContext> mcIter = mcSet.iterator();
1048 FlatMethod callerFM = state.getMethodFlat(callerMD);
1050 while (mcIter.hasNext()) {
1051 MethodContext mc = mcIter.next();
1053 Set<FlatNode> visited = new HashSet<FlatNode>();
1054 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
1055 flatNodesToVisit.add(callerFM);
1057 while (!flatNodesToVisit.isEmpty()) {
1058 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
1059 flatNodesToVisit.remove(fn);
1061 analyzeRelatedAllocationSite_NodeAction(fn, mc, calleeMC,
1062 paramIndexSet,visitedHRN);
1064 flatNodesToVisit.remove(fn);
1067 for (int i = 0; i < fn.numNext(); i++) {
1068 FlatNode nn = fn.getNext(i);
1069 if (!visited.contains(nn)) {
1070 flatNodesToVisit.add(nn);
1079 private void analyzeRelatedAllocationSite_NodeAction(FlatNode fn, MethodContext callerMC,
1080 MethodContext calleeMC,
1081 HashSet<Integer> paramIndexSet, HashSet<HeapRegionNode> visitedHRN) {
1083 OwnershipGraph og = ownAnalysis
1084 .getOwnvershipGraphByMethodContext(callerMC);
1086 switch (fn.kind()) {
1088 case FKind.FlatCall: {
1090 FlatCall fc = (FlatCall) fn;
1093 if(fc.numArgs()>0 && fc.getMethod().equals(calleeMC.getDescriptor())){
1094 MethodContext calleeMCfromOG = ownAnalysis.getCalleeMethodContext(
1097 // disable below condition. currently collect all possible
1098 // allocation sites without regarding method context
1100 // if (calleeMC.equals(calleeMCfromOG)) { // in this case, this
1101 // method context calls corresponding callee.
1104 if (((MethodDescriptor) calleeMC.getDescriptor()).isStatic()) {
1110 for (Iterator iterator = paramIndexSet.iterator(); iterator
1112 Integer integer = (Integer) iterator.next();
1114 int paramIdx = integer - base;
1115 if (paramIdx >= 0) {
1116 // if paramIdx is less than 0, assumes that it is
1117 // related with wrong method contexts.
1118 TempDescriptor arg = fc.getArg(paramIdx);
1119 LabelNode argLN = og.td2ln.get(arg);
1120 if (argLN != null) {
1121 Iterator<ReferenceEdge> iterEdge = argLN
1122 .iteratorToReferencees();
1123 while (iterEdge.hasNext()) {
1124 ReferenceEdge referenceEdge = (ReferenceEdge) iterEdge
1127 HeapRegionNode dstHRN = referenceEdge.getDst();
1128 if (dstHRN.isParameter()) {
1129 if (!visitedHRN.contains(dstHRN)) {
1130 setupRelatedAllocSiteAnalysis(og, callerMC,
1131 dstHRN, visitedHRN);
1134 flagAllocationSite(callerMC, dstHRN
1135 .getAllocationSite());
1152 private void setupRelatedAllocSiteAnalysis(OwnershipGraph og,
1153 MethodContext mc, HeapRegionNode dstHRN,
1154 HashSet<HeapRegionNode> visitedHRN) {
1156 HashSet<Integer> paramIndexSet = new HashSet<Integer>();
1158 // collect corresponding param index
1159 Set<Integer> pIndexSet = og.idPrimary2paramIndexSet.get(dstHRN.getID());
1160 if (pIndexSet != null) {
1161 for (Iterator iterator = pIndexSet.iterator(); iterator.hasNext();) {
1162 Integer integer = (Integer) iterator.next();
1163 paramIndexSet.add(integer);
1167 Set<Integer> sIndexSet = og.idSecondary2paramIndexSet.get(dstHRN
1169 if (sIndexSet != null) {
1170 for (Iterator iterator = sIndexSet.iterator(); iterator.hasNext();) {
1171 Integer integer = (Integer) iterator.next();
1172 paramIndexSet.add(integer);
1176 if (mc.getDescriptor() instanceof MethodDescriptor) {
1177 Set callerSet = callGraph.getCallerSet((MethodDescriptor) mc
1179 for (Iterator iterator = callerSet.iterator(); iterator.hasNext();) {
1180 Object obj = (Object) iterator.next();
1181 if (obj instanceof MethodDescriptor) {
1182 MethodDescriptor callerMD = (MethodDescriptor) obj;
1184 if(callerMD.equals(mc.getDescriptor())){
1187 analyzeRelatedAllocationSite(callerMD, mc, paramIndexSet,visitedHRN);
1194 private void effects_nodeActions(MethodContext mc, FlatNode fn,
1195 FlatSESEEnterNode currentSESE, CallGraph callGraph,Hashtable<TempDescriptor, TempDescriptor> invarMap) {
1197 OwnershipGraph og = ownAnalysis.getOwnvershipGraphByMethodContext(mc);
1199 switch (fn.kind()) {
1201 case FKind.FlatSESEEnterNode: {
1203 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
1204 assert fsen.equals(currentSESE);
1206 // if(fsen.getParent()!=null && fsen.getParent().getSeseEffectsSet()!=null){
1207 // Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> strongTable=
1208 // fsen.getParent().getSeseEffectsSet().getStrongUpdateTable();
1209 // fsen.getSeseEffectsSet().getStrongUpdateTable().putAll(strongTable);
1213 if (!fsen.getIsCallerSESEplaceholder()) {
1214 // uniquely taint each live-in variable
1215 Set<TempDescriptor> set = fsen.getInVarSet();
1217 // Set<TempDescriptor> tempSet=fsen.getOutVarSet();
1218 // for (Iterator iterator = tempSet.iterator(); iterator.hasNext();) {
1219 // TempDescriptor tempDescriptor = (TempDescriptor) iterator
1221 // set.add(tempDescriptor);
1224 Iterator<TempDescriptor> iter = set.iterator();
1226 while (iter.hasNext()) {
1227 TempDescriptor td = iter.next();
1228 LabelNode ln = og.td2ln.get(td);
1230 int taint = (int) Math.pow(2, idx);
1231 taintLabelNode(ln, taint);
1233 // collects related allocation sites
1234 Iterator<ReferenceEdge> referenceeIter = ln
1235 .iteratorToReferencees();
1236 while (referenceeIter.hasNext()) {
1237 ReferenceEdge referenceEdge = (ReferenceEdge) referenceeIter
1239 HeapRegionNode dstHRN = referenceEdge.getDst();
1240 if (dstHRN.isParameter()) {
1242 HashSet<HeapRegionNode> visitedHRN = new HashSet<HeapRegionNode>();
1243 visitedHRN.add(dstHRN);
1244 setupRelatedAllocSiteAnalysis(og, mc, dstHRN,
1248 flagAllocationSite(mc, dstHRN
1249 .getAllocationSite());
1262 case FKind.FlatSESEExitNode: {
1263 FlatSESEExitNode fsexit = (FlatSESEExitNode) fn;
1265 if (!fsexit.getFlatEnter().getIsCallerSESEplaceholder()) {
1267 FlatSESEEnterNode enterNode = fsexit.getFlatEnter();
1268 FlatSESEEnterNode parent = enterNode.getParent();
1269 if (parent != null) {
1271 SESEEffectsSet set = enterNode.getSeseEffectsSet();
1272 Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> readTable = set
1274 Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> parentReadTable = parent
1275 .getSeseEffectsSet().getReadTable();
1276 Set<TempDescriptor> keys = readTable.keySet();
1277 Iterator<TempDescriptor> keyIter = keys.iterator();
1278 while (keyIter.hasNext()) {
1279 TempDescriptor td = (TempDescriptor) keyIter.next();
1280 HashSet<SESEEffectsKey> effectsSet = readTable.get(td);
1281 HashSet<SESEEffectsKey> parentEffectsSet = parentReadTable
1283 if (parentEffectsSet == null) {
1284 parentEffectsSet = new HashSet<SESEEffectsKey>();
1287 for (Iterator iterator = effectsSet.iterator(); iterator
1289 SESEEffectsKey seseKey = (SESEEffectsKey) iterator
1291 parentEffectsSet.add(new SESEEffectsKey(seseKey
1292 .getFieldDescriptor(), seseKey
1293 .getTypeDescriptor(), seseKey.getHRNId(),
1294 seseKey.getHRNUniqueId()));
1297 parentReadTable.put(td, parentEffectsSet);
1300 Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> writeTable = set
1302 Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> parentWriteTable = parent
1303 .getSeseEffectsSet().getWriteTable();
1304 keys = writeTable.keySet();
1305 keyIter = keys.iterator();
1306 while (keyIter.hasNext()) {
1307 TempDescriptor td = (TempDescriptor) keyIter.next();
1308 HashSet<SESEEffectsKey> effectsSet = writeTable.get(td);
1309 HashSet<SESEEffectsKey> parentEffectsSet = parentWriteTable
1311 if (parentEffectsSet == null) {
1312 parentEffectsSet = new HashSet<SESEEffectsKey>();
1315 for (Iterator iterator = effectsSet.iterator(); iterator
1317 SESEEffectsKey seseKey = (SESEEffectsKey) iterator
1319 parentEffectsSet.add(new SESEEffectsKey(seseKey
1320 .getFieldDescriptor(), seseKey
1321 .getTypeDescriptor(), seseKey.getHRNId(),
1322 seseKey.getHRNUniqueId()));
1325 parentWriteTable.put(td, parentEffectsSet);
1328 Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> strongUpdateTable = set
1329 .getStrongUpdateTable();
1330 Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> parentstrongUpdateTable = parent
1331 .getSeseEffectsSet().getStrongUpdateTable();
1332 keys = strongUpdateTable.keySet();
1333 keyIter = keys.iterator();
1334 while (keyIter.hasNext()) {
1335 TempDescriptor td = (TempDescriptor) keyIter.next();
1336 HashSet<SESEEffectsKey> effectsSet = strongUpdateTable
1338 HashSet<SESEEffectsKey> parentEffectsSet = parentstrongUpdateTable
1340 if (parentEffectsSet == null) {
1341 parentEffectsSet = new HashSet<SESEEffectsKey>();
1344 for (Iterator iterator = effectsSet.iterator(); iterator
1346 SESEEffectsKey seseKey = (SESEEffectsKey) iterator
1348 parentEffectsSet.add(new SESEEffectsKey(seseKey
1349 .getFieldDescriptor(), seseKey
1350 .getTypeDescriptor(), seseKey.getHRNId(),
1351 seseKey.getHRNUniqueId()));
1354 parentstrongUpdateTable.put(td, parentEffectsSet);
1364 case FKind.FlatFieldNode: {
1366 FlatFieldNode ffn = (FlatFieldNode) fn;
1367 TempDescriptor src = ffn.getSrc();
1368 FieldDescriptor field = ffn.getField();
1370 LabelNode srcLN = og.td2ln.get(src);
1371 if (srcLN != null) {
1372 HashSet<TempDescriptor> affectedTDSet = getAccessedTaintNodeSet(srcLN);
1373 Iterator<TempDescriptor> affectedIter = affectedTDSet
1375 while (affectedIter.hasNext()) {
1376 TempDescriptor affectedTD = affectedIter.next();
1378 if (currentSESE.getInVarSet().contains(affectedTD) || ((!currentSESE.getInVarSet().contains(affectedTD)) && currentSESE.getOutVarSet().contains(affectedTD)) ) {
1380 HashSet<HeapRegionNode> hrnSet = getReferenceHeapIDSet(
1382 Iterator<HeapRegionNode> hrnIter = hrnSet.iterator();
1383 while (hrnIter.hasNext()) {
1384 HeapRegionNode hrn = hrnIter.next();
1386 Iterator<ReferenceEdge> referencers = hrn
1387 .iteratorToReferencers();
1388 while (referencers.hasNext()) {
1389 ReferenceEdge referenceEdge = (ReferenceEdge) referencers
1391 if (field.getSymbol().equals(
1392 referenceEdge.getField())) {
1394 HeapRegionNode refHRN = og.id2hrn
1395 .get(referenceEdge.getDst().getID());
1398 .readEffects(affectedTD, field
1400 src.getType(), refHRN);
1408 // handle tainted case
1410 Iterator<ReferenceEdge> edgeIter = srcLN
1411 .iteratorToReferencees();
1412 while (edgeIter.hasNext()) {
1413 ReferenceEdge edge = edgeIter.next();
1414 HeapRegionNode accessHRN = edge.getDst();
1415 // / follow the chain of reference to identify possible
1417 Iterator<ReferenceEdge> referIter = accessHRN
1418 .iteratorToReferencers();
1419 while (referIter.hasNext()) {
1420 ReferenceEdge referEdge = (ReferenceEdge) referIter
1423 // if (referEdge.getTaintIdentifier() >0 ||
1424 // referEdge.getSESETaintIdentifier()>0 ) {
1425 HashSet<TempDescriptor> referSet = new HashSet<TempDescriptor>();
1426 followReference(accessHRN, referSet,
1427 new HashSet<HeapRegionNode>(), currentSESE);
1429 Iterator<TempDescriptor> referSetIter = referSet
1431 while (referSetIter.hasNext()) {
1432 TempDescriptor tempDescriptor = (TempDescriptor) referSetIter
1434 currentSESE.readEffects(tempDescriptor, field
1435 .getSymbol(), src.getType(), accessHRN);
1440 if (edge.getTaintIdentifier() > 0
1441 || edge.getSESETaintIdentifier() > 0) {
1443 affectedTDSet = getReferenceNodeSet(accessHRN);
1444 affectedIter = affectedTDSet.iterator();
1445 while (affectedIter.hasNext()) {
1446 TempDescriptor affectedTD = affectedIter.next();
1448 if (currentSESE.getInVarSet().contains(affectedTD)) {
1450 HashSet<HeapRegionNode> hrnSet = getReferenceHeapIDSet(
1452 Iterator<HeapRegionNode> hrnIter = hrnSet
1454 while (hrnIter.hasNext()) {
1455 HeapRegionNode hrn = hrnIter.next();
1456 currentSESE.readEffects(affectedTD, field
1457 .getSymbol(), src.getType(), hrn);
1470 case FKind.FlatOpNode:{
1472 FlatOpNode fon=(FlatOpNode)fn;
1473 TempDescriptor dest=fon.getDest();
1474 TempDescriptor src=fon.getLeft();
1476 // if(!currentSESE.getIsCallerSESEplaceholder()){
1477 if( fon.getOp().getOp() ==Operation.ASSIGN && ( currentSESE.getInVarSet().contains(src) || (currentSESE.getOutVarSet().contains(src)))){
1478 invarMap.put(dest, src);
1484 case FKind.FlatNew:{
1485 FlatNew fnew=(FlatNew)fn;
1486 TempDescriptor dst=fnew.getDst();
1487 if(dst.getType().isArray()){
1488 currentSESE.getSeseEffectsSet().addStrongUpdateVar(dst, new SESEEffectsKey("", dst.getType(), new Integer(0), ""));
1493 case FKind.FlatElementNode:{
1495 FlatElementNode fsen=(FlatElementNode)fn;
1496 TempDescriptor src = fsen.getSrc();
1498 if(invarMap.containsKey(src)){
1499 TempDescriptor invarTD=invarMap.get(src);
1500 currentSESE.getSeseEffectsSet().addReadingVar(invarTD, new SESEEffectsKey("", src.getType(), new Integer(0), ""));
1505 case FKind.FlatSetElementNode:{
1507 FlatSetElementNode fsen=(FlatSetElementNode)fn;
1508 TempDescriptor dst = fsen.getDst();
1510 if(invarMap.containsKey(dst)){
1511 TempDescriptor invarTD=invarMap.get(dst);
1513 SESEEffectsSet effectSet=currentSESE.getSeseEffectsSet();
1514 ///// if write effects occurs through variable which was strongly updated, ignore it?
1515 if(effectSet.getStrongUpdateSet(invarTD)!=null && effectSet.getStrongUpdateSet(invarTD).size()>0){
1516 SESEEffectsKey key=new SESEEffectsKey("", dst.getType(), new Integer(0), "");
1517 key.setStrong(true);
1518 currentSESE.getSeseEffectsSet().addWritingVar(invarTD, key);
1520 currentSESE.getSeseEffectsSet().addWritingVar(invarTD, new SESEEffectsKey("", dst.getType(), new Integer(0), ""));
1528 case FKind.FlatSetFieldNode: {
1530 FlatSetFieldNode fsen = (FlatSetFieldNode) fn;
1531 TempDescriptor dst = fsen.getDst();
1532 FieldDescriptor field = fsen.getField();
1534 LabelNode dstLN = og.td2ln.get(dst);
1536 if (dstLN != null) {
1538 // check possible strong updates
1539 boolean strongUpdate = false;
1541 if (!field.getType().isImmutable() || field.getType().isArray()) {
1542 Iterator<ReferenceEdge> itrXhrn = dstLN
1543 .iteratorToReferencees();
1544 while (itrXhrn.hasNext()) {
1545 ReferenceEdge edgeX = itrXhrn.next();
1546 HeapRegionNode hrnX = edgeX.getDst();
1548 // we can do a strong update here if one of two cases
1551 && field != OwnershipAnalysis
1552 .getArrayField(field.getType())
1553 && ((hrnX.getNumReferencers() == 1) || // case 1
1554 (hrnX.isSingleObject() && dstLN
1555 .getNumReferencees() == 1) // case 2
1557 strongUpdate = true;
1561 HashSet<TempDescriptor> affectedTDSet = getAccessedTaintNodeSet(dstLN);
1562 Iterator<TempDescriptor> affectedIter = affectedTDSet
1565 while (affectedIter.hasNext()) {
1566 TempDescriptor affectedTD = affectedIter.next();
1567 if (currentSESE.getInVarSet().contains(affectedTD) || ((!currentSESE.getInVarSet().contains(affectedTD)) && currentSESE.getOutVarSet().contains(affectedTD)) ) {
1569 HashSet<HeapRegionNode> hrnSet = getReferenceHeapIDSet(
1571 Iterator<HeapRegionNode> hrnIter = hrnSet.iterator();
1572 while (hrnIter.hasNext()) {
1573 HeapRegionNode hrn = hrnIter.next();
1574 Iterator<ReferenceEdge> referencers = hrn
1575 .iteratorToReferencers();
1576 while (referencers.hasNext()) {
1577 ReferenceEdge referenceEdge = (ReferenceEdge) referencers
1579 if (field.getSymbol().equals(
1580 referenceEdge.getField())) {
1582 HeapRegionNode refHRN = og.id2hrn
1583 .get(referenceEdge.getDst().getID());
1584 currentSESE.writeEffects(affectedTD, field
1585 .getSymbol(), dst.getType(),
1586 refHRN, strongUpdate);
1594 // handle tainted case
1595 Iterator<ReferenceEdge> edgeIter = dstLN
1596 .iteratorToReferencees();
1597 while (edgeIter.hasNext()) {
1598 ReferenceEdge edge = edgeIter.next();
1600 HeapRegionNode accessHRN = edge.getDst();
1601 // / follow the chain of reference to identify possible
1603 Iterator<ReferenceEdge> referIter = accessHRN
1604 .iteratorToReferencers();
1605 while (referIter.hasNext()) {
1606 ReferenceEdge referEdge = (ReferenceEdge) referIter
1609 // if (referEdge.getTaintIdentifier() > 0 ||
1610 // referEdge.getSESETaintIdentifier() > 0 ) {
1611 HashSet<TempDescriptor> referSet = new HashSet<TempDescriptor>();
1612 followReference(accessHRN, referSet,
1613 new HashSet<HeapRegionNode>(), currentSESE);
1614 Iterator<TempDescriptor> referSetIter = referSet
1616 while (referSetIter.hasNext()) {
1617 TempDescriptor tempDescriptor = (TempDescriptor) referSetIter
1619 SESEEffectsSet effectSet=currentSESE.getSeseEffectsSet();
1620 ///// if write effects occurs through variable which was strongly updated, ignore it?
1621 if(effectSet.getStrongUpdateSet(tempDescriptor)!=null && effectSet.getStrongUpdateSet(tempDescriptor).size()>0){
1622 // System.out.println("not write effect?");
1624 currentSESE.writeEffects(tempDescriptor, field
1625 .getSymbol(), dst.getType(), accessHRN,
1633 if (edge.getTaintIdentifier() > 0
1634 || edge.getSESETaintIdentifier() > 0) {
1635 affectedTDSet = getReferenceNodeSet(accessHRN);
1636 affectedIter = affectedTDSet.iterator();
1637 while (affectedIter.hasNext()) {
1638 TempDescriptor affectedTD = affectedIter.next();
1639 if (currentSESE.getInVarSet().contains(affectedTD)) {
1641 HashSet<HeapRegionNode> hrnSet = getReferenceHeapIDSet(
1643 Iterator<HeapRegionNode> hrnIter = hrnSet
1645 while (hrnIter.hasNext()) {
1646 HeapRegionNode hrn = hrnIter.next();
1647 currentSESE.writeEffects(affectedTD, field
1648 .getSymbol(), dst.getType(), hrn,
1664 case FKind.FlatCall: {
1665 FlatCall fc = (FlatCall) fn;
1667 MethodContext calleeMC = ownAnalysis.getCalleeMethodContext(mc, fc);
1669 MethodEffects me = ownAnalysis.getMethodEffectsAnalysis()
1670 .getMethodEffectsByMethodContext(calleeMC);
1673 OwnershipGraph calleeOG = ownAnalysis
1674 .getOwnvershipGraphByMethodContext(calleeMC);
1677 FlatMethod fm = state.getMethodFlat(fc.getMethod());
1678 ParameterDecomposition decomp = new ParameterDecomposition(
1679 ownAnalysis, fc, fm, calleeMC, calleeOG, og);
1682 if (((MethodDescriptor) calleeMC.getDescriptor()).isStatic()) {
1688 for (int i = 0; i < fc.numArgs()+base; i++) {
1690 TempDescriptor arg ;
1691 Set<EffectsKey> readSet;
1692 Set<EffectsKey> writeSet;
1693 Set<EffectsKey> strongUpdateSet;
1697 boolean isThis=false;
1698 if(i==fc.numArgs()){
1701 Integer hrnPrimaryID = calleeOG.paramIndex2idPrimary.get(paramIdx);
1702 Integer hrnSecondaryID = calleeOG.paramIndex2idSecondary.get(paramIdx);
1703 readSet = me.getEffects().getReadingSet(
1705 writeSet = me.getEffects().getWritingSet(
1707 strongUpdateSet = me.getEffects()
1708 .getStrongUpdateSet(0);
1713 readSet = me.getEffects().getReadingSet(
1715 writeSet = me.getEffects().getWritingSet(
1717 strongUpdateSet = me.getEffects()
1718 .getStrongUpdateSet(i + base);
1721 LabelNode argLN = og.td2ln.get(arg);
1722 if (argLN != null) {
1723 HashSet<TempDescriptor> affectedTDSet = getAccessedTaintNodeSet(argLN);
1724 Iterator<TempDescriptor> affectedIter = affectedTDSet
1727 while (affectedIter.hasNext()) {
1729 TempDescriptor affectedTD = affectedIter.next();
1731 if (currentSESE.getInVarSet().contains(affectedTD)) {
1732 // Integer hrnPrimaryID = calleeOG.paramIndex2idPrimary.get(paramIdx);
1733 // Integer hrnSecondaryID = calleeOG.paramIndex2idSecondary.get(paramIdx);
1734 // System.out.println("primID="+hrnPrimaryID);
1735 // System.out.println("seconID="+hrnSecondaryID);
1738 if (currentSESE.getInVarSet().contains(affectedTD)) {
1740 if (readSet != null) {
1741 Iterator<EffectsKey> readIter = readSet
1743 while (readIter.hasNext()) {
1744 EffectsKey key = readIter.next();
1745 Set<Integer> hrnSet = getCallerHRNId(
1746 new Integer(paramIdx), calleeOG,
1747 key.getHRNId(), decomp);
1748 Iterator<Integer> hrnIter = hrnSet
1750 while (hrnIter.hasNext()) {
1751 Integer hrnID = (Integer) hrnIter
1754 HeapRegionNode refHRN = og.id2hrn
1757 currentSESE.readEffects(affectedTD, key
1758 .getFieldDescriptor(), key
1759 .getTypeDescriptor(), refHRN);
1765 if (writeSet != null) {
1766 Iterator<EffectsKey> writeIter = writeSet
1768 while (writeIter.hasNext()) {
1769 EffectsKey key = writeIter.next();
1771 Set<Integer> hrnSet = getCallerHRNId(
1772 new Integer(paramIdx), calleeOG,
1773 key.getHRNId(), decomp);
1774 Iterator<Integer> hrnIter = hrnSet
1776 while (hrnIter.hasNext()) {
1777 Integer hrnID = (Integer) hrnIter
1780 HeapRegionNode refHRN = og.id2hrn
1782 currentSESE.writeEffects(affectedTD,
1783 key.getFieldDescriptor(), key
1784 .getTypeDescriptor(),
1791 if (strongUpdateSet != null) {
1792 Iterator<EffectsKey> strongUpdateIter = strongUpdateSet
1794 while (strongUpdateIter.hasNext()) {
1795 EffectsKey key = strongUpdateIter.next();
1797 Set<Integer> hrnSet = getCallerHRNId(
1798 new Integer(paramIdx), calleeOG,
1799 key.getHRNId(), decomp);
1800 Iterator<Integer> hrnIter = hrnSet
1802 while (hrnIter.hasNext()) {
1803 Integer hrnID = (Integer) hrnIter
1806 HeapRegionNode refHRN = og.id2hrn
1808 currentSESE.writeEffects(affectedTD,
1809 key.getFieldDescriptor(), key
1810 .getTypeDescriptor(),
1831 private void flagAllocationSite(MethodContext mc, AllocationSite ac){
1833 HashSet<AllocationSite> set=mapMethodContextToLiveInAllocationSiteSet.get(mc);
1835 set=new HashSet<AllocationSite>();
1838 mapMethodContextToLiveInAllocationSiteSet.put(mc, set);
1841 private void followReference(HeapRegionNode hrn,HashSet<TempDescriptor> tdSet, HashSet<HeapRegionNode> visited, FlatSESEEnterNode currentSESE){
1843 Iterator<ReferenceEdge> referIter=hrn.iteratorToReferencers();
1844 // check whether hrn is referenced by TD
1845 while (referIter.hasNext()) {
1846 ReferenceEdge referEdge = (ReferenceEdge) referIter.next();
1847 if(referEdge.getSrc() instanceof LabelNode){
1848 LabelNode ln=(LabelNode)referEdge.getSrc();
1849 if(currentSESE.getInVarSet().contains(ln.getTempDescriptor())){
1850 tdSet.add(ln.getTempDescriptor());
1852 }else if(referEdge.getSrc() instanceof HeapRegionNode){
1853 HeapRegionNode nextHRN=(HeapRegionNode)referEdge.getSrc();
1854 if(!visited.contains(nextHRN)){
1855 visited.add(nextHRN);
1856 followReference(nextHRN,tdSet,visited,currentSESE);
1864 private Set<Integer> getCallerHRNId(Integer paramIdx,
1865 OwnershipGraph calleeOG, Integer calleeHRNId,
1866 ParameterDecomposition paramDecom) {
1868 Integer hrnPrimaryID = calleeOG.paramIndex2idPrimary.get(paramIdx);
1869 Integer hrnSecondaryID = calleeOG.paramIndex2idSecondary.get(paramIdx);
1871 if (calleeHRNId.equals(hrnPrimaryID)) {
1872 // it references to primary param heap region
1873 return paramDecom.getParamObject_hrnIDs(paramIdx);
1874 } else if (calleeHRNId.equals(hrnSecondaryID)) {
1875 // it references to secondary param heap region
1876 return paramDecom.getParamReachable_hrnIDs(paramIdx);
1879 return new HashSet<Integer>();
1882 private void taintLabelNode(LabelNode ln, int identifier) {
1884 Iterator<ReferenceEdge> edgeIter = ln.iteratorToReferencees();
1885 while (edgeIter.hasNext()) {
1886 ReferenceEdge edge = edgeIter.next();
1887 HeapRegionNode hrn = edge.getDst();
1889 Iterator<ReferenceEdge> edgeReferencerIter = hrn
1890 .iteratorToReferencers();
1891 while (edgeReferencerIter.hasNext()) {
1892 ReferenceEdge referencerEdge = edgeReferencerIter.next();
1893 OwnershipNode node = referencerEdge.getSrc();
1894 if (node instanceof LabelNode) {
1895 referencerEdge.unionSESETaintIdentifier(identifier);
1896 }else if(node instanceof HeapRegionNode){
1897 referencerEdge.unionSESETaintIdentifier(identifier);
1905 private HashSet<TempDescriptor> getReferenceNodeSet(HeapRegionNode hrn){
1907 HashSet<TempDescriptor> returnSet=new HashSet<TempDescriptor>();
1909 Iterator<ReferenceEdge> edgeIter=hrn.iteratorToReferencers();
1910 while(edgeIter.hasNext()){
1911 ReferenceEdge edge=edgeIter.next();
1912 if(edge.getSrc() instanceof LabelNode){
1913 LabelNode ln=(LabelNode)edge.getSrc();
1914 returnSet.add(ln.getTempDescriptor());
1923 private HashSet<HeapRegionNode> getReferenceHeapIDSet(OwnershipGraph og, TempDescriptor td){
1925 HashSet<HeapRegionNode> returnSet=new HashSet<HeapRegionNode>();
1927 LabelNode ln=og.td2ln.get(td);
1929 Iterator<ReferenceEdge> edgeIter=ln.iteratorToReferencees();
1930 while(edgeIter.hasNext()){
1931 ReferenceEdge edge=edgeIter.next();
1932 HeapRegionNode hrn=edge.getDst();
1940 private HashSet<TempDescriptor> getAccessedTaintNodeSet(LabelNode ln) {
1942 HashSet<TempDescriptor> returnSet = new HashSet<TempDescriptor>();
1944 Iterator<ReferenceEdge> edgeIter = ln.iteratorToReferencees();
1945 while (edgeIter.hasNext()) {
1946 ReferenceEdge edge = edgeIter.next();
1947 HeapRegionNode hrn = edge.getDst();
1949 Iterator<ReferenceEdge> edgeReferencerIter = hrn
1950 .iteratorToReferencers();
1951 while (edgeReferencerIter.hasNext()) {
1952 ReferenceEdge referencerEdge = edgeReferencerIter.next();
1954 if (referencerEdge.getSrc() instanceof LabelNode) {
1955 if (!((LabelNode) referencerEdge.getSrc()).equals(ln)) {
1957 if (referencerEdge.getSESETaintIdentifier() > 0) {
1958 TempDescriptor td = ((LabelNode) referencerEdge
1959 .getSrc()).getTempDescriptor();
1972 private HashSet<ReferenceEdge> getRefEdgeSetReferenceToSameHRN(
1973 OwnershipGraph og, TempDescriptor td) {
1975 HashSet<ReferenceEdge> returnSet = new HashSet<ReferenceEdge>();
1977 HashSet<HeapRegionNode> heapIDs = getReferenceHeapIDSet(og, td);
1978 for (Iterator<HeapRegionNode> iterator = heapIDs.iterator(); iterator
1980 HeapRegionNode heapRegionNode = (HeapRegionNode) iterator.next();
1981 Iterator<ReferenceEdge> referenceeIter = heapRegionNode
1982 .iteratorToReferencees();
1983 while (referenceeIter.hasNext()) {
1984 ReferenceEdge edge = (ReferenceEdge) referenceeIter.next();
1985 if (edge.getSrc() instanceof HeapRegionNode) {
1986 returnSet.add(edge);
1993 private HashSet<TempDescriptor> getTempDescSetReferenceToSameHRN(
1994 OwnershipGraph og, TempDescriptor td) {
1996 HashSet<TempDescriptor> returnSet = new HashSet<TempDescriptor>();
1998 HashSet<HeapRegionNode> heapIDs = getReferenceHeapIDSet(og, td);
1999 for (Iterator<HeapRegionNode> iterator = heapIDs.iterator(); iterator
2001 HeapRegionNode heapRegionNode = (HeapRegionNode) iterator.next();
2002 Iterator<ReferenceEdge> referencerIter = heapRegionNode
2003 .iteratorToReferencers();
2004 while (referencerIter.hasNext()) {
2005 ReferenceEdge edge = (ReferenceEdge) referencerIter.next();
2006 if (edge.getSrc() instanceof LabelNode) {
2007 LabelNode ln = (LabelNode) edge.getSrc();
2008 returnSet.add(ln.getTempDescriptor());
2015 private void DFSVisit( MethodDescriptor md,
2016 LinkedList<MethodDescriptor> sorted,
2017 HashSet<MethodDescriptor> discovered, JavaCallGraph javaCallGraph) {
2021 Iterator itr = javaCallGraph.getCallerSet(md).iterator();
2022 while (itr.hasNext()) {
2023 MethodDescriptor mdCaller = (MethodDescriptor) itr.next();
2025 if (!discovered.contains(mdCaller)) {
2026 DFSVisit(mdCaller, sorted, discovered, javaCallGraph);
2030 sorted.addFirst(md);
2034 private LinkedList<MethodDescriptor> topologicalSort(Set set,
2035 JavaCallGraph javaCallGraph) {
2036 HashSet<MethodDescriptor> discovered = new HashSet<MethodDescriptor>();
2037 LinkedList<MethodDescriptor> sorted = new LinkedList<MethodDescriptor>();
2039 Iterator<MethodDescriptor> itr = set.iterator();
2040 while (itr.hasNext()) {
2041 MethodDescriptor md = itr.next();
2043 if (!discovered.contains(md)) {
2044 DFSVisit(md, sorted, discovered, javaCallGraph);
2051 private void calculateCliqueCovering(ConflictGraph conflictGraph) {
2053 HashSet<ConflictEdge> tocover = conflictGraph.getEdgeSet();
2054 HashSet<SESELock> lockSet=new HashSet<SESELock>();
2056 while (!tocover.isEmpty()) {
2057 ConflictEdge edge = (ConflictEdge) tocover.iterator().next();
2058 tocover.remove(edge);
2060 SESELock seseLock = new SESELock();
2061 seseLock.addEdge(edge);
2063 boolean changed = false;
2066 for (Iterator edgeit = tocover.iterator(); edgeit.hasNext();) {
2067 ConflictEdge newEdge = (ConflictEdge) edgeit.next();
2068 if (newEdge.getVertexU() == newEdge.getVertexV()
2069 && seseLock.containsConflictNode(newEdge
2071 // for self-edge case
2072 tocover.remove(newEdge);
2074 break;// exit iterator loop
2075 } else if (seseLock.testEdge(newEdge)) {
2077 ConflictNode nodeToAdd = seseLock
2078 .containsConflictNode(newEdge.getVertexU()) ? newEdge
2080 : newEdge.getVertexU();
2082 for (Iterator newEdgeIter = nodeToAdd.getEdgeSet()
2083 .iterator(); newEdgeIter.hasNext();) {
2084 ConflictEdge ne = (ConflictEdge) newEdgeIter.next();
2085 if (seseLock.containsConflictNode(ne.getVertexU())) {
2087 } else if (seseLock.containsConflictNode(ne
2092 // Add in new node to lockset
2093 seseLock.addEdge(newEdge);
2095 break; // exit iterator loop
2100 seseLock.setID(ConflictGraph.generateUniqueCliqueID());
2101 lockSet.add(seseLock);
2105 //build map from synthsized locks to conflict graph
2106 conflictGraphLockMap.put(conflictGraph, lockSet);
2111 private void synthesizeLocks(){
2113 // conflictGraphResults.put(seseSummary.getCurrentSESE(),
2116 Set<Entry<FlatNode,ConflictGraph>> graphEntrySet=conflictGraphResults.entrySet();
2117 for (Iterator iterator = graphEntrySet.iterator(); iterator.hasNext();) {
2118 Entry<FlatNode, ConflictGraph> graphEntry = (Entry<FlatNode, ConflictGraph>) iterator
2120 FlatNode sese=graphEntry.getKey();
2121 ConflictGraph conflictGraph=graphEntry.getValue();
2122 calculateCliqueCovering(conflictGraph);
2127 private void makeConflictGraph() {
2128 Iterator<Descriptor> methItr = ownAnalysis.descriptorsToAnalyze
2130 while (methItr.hasNext()) {
2131 Descriptor d = methItr.next();
2132 FlatMethod fm = state.getMethodFlat(d);
2134 HashSet<MethodContext> mcSet = ownAnalysisForSESEConflicts
2135 .getAllMethodContextSetByDescriptor(fm.getMethod());
2136 Iterator<MethodContext> mcIter = mcSet.iterator();
2138 while (mcIter.hasNext()) {
2139 MethodContext mc = mcIter.next();
2141 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
2142 flatNodesToVisit.add(fm);
2144 Set<FlatNode> visited = new HashSet<FlatNode>();
2146 SESESummary summary = new SESESummary(null, fm);
2147 seseSummaryMap.put(fm, summary);
2149 Hashtable<TempDescriptor, TempDescriptor> invarMap=new Hashtable<TempDescriptor,TempDescriptor>();
2151 while (!flatNodesToVisit.isEmpty()) {
2152 Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
2153 FlatNode fn = fnItr.next();
2155 flatNodesToVisit.remove(fn);
2158 // Adding Stall Node of current program statement
2159 ParentChildConflictsMap currentConflictsMap = conflictsResults
2162 Hashtable<TempDescriptor, StallSite> stallMap = currentConflictsMap
2165 Set<Entry<TempDescriptor, StallSite>> entrySet = stallMap
2168 SESESummary seseSummary = seseSummaryMap.get(fn);
2170 ConflictGraph conflictGraph = null;
2171 conflictGraph = conflictGraphResults.get(seseSummary
2174 if (conflictGraph == null) {
2175 conflictGraph = new ConflictGraph();
2177 for (Iterator<Entry<TempDescriptor, StallSite>> iterator2 = entrySet
2178 .iterator(); iterator2.hasNext();) {
2179 Entry<TempDescriptor, StallSite> entry = iterator2
2181 TempDescriptor td = entry.getKey();
2182 StallSite stallSite = entry.getValue();
2185 OwnershipGraph og = ownAnalysisForSESEConflicts
2186 .getOwnvershipGraphByMethodContext(mc);
2187 Set<Set> reachabilitySet = calculateReachabilitySet(og,
2189 conflictGraph.addStallNode(td, fm, stallSite,
2194 if (conflictGraph.id2cn.size() > 0) {
2195 conflictGraphResults.put(seseSummary.getCurrentSESE(),
2199 conflictGraph_nodeAction(mc, fm, fn,invarMap);
2201 for (int i = 0; i < fn.numNext(); i++) {
2202 FlatNode nn = fn.getNext(i);
2203 if (!visited.contains(nn)) {
2204 flatNodesToVisit.add(nn);
2207 } // end of while(flatNodesToVisit)
2209 } // end of while(mcIter)
2213 // decide fine-grain edge or coarse-grain edge among all vertexes by pair-wise comparison
2214 Enumeration<FlatNode> keyEnum1=conflictGraphResults.keys();
2215 while (keyEnum1.hasMoreElements()) {
2216 FlatNode flatNode = (FlatNode) keyEnum1.nextElement();
2217 ConflictGraph conflictGraph=conflictGraphResults.get(flatNode);
2218 conflictGraph.analyzeConflicts();
2219 conflictGraph.addPseudoEdgeBetweenReadOnlyNode();
2220 conflictGraphResults.put(flatNode, conflictGraph);
2223 // add pseudo-edge for a pair of read-only node
2224 keyEnum1=conflictGraphResults.keys();
2225 while (keyEnum1.hasMoreElements()) {
2226 FlatNode flatNode = (FlatNode) keyEnum1.nextElement();
2227 ConflictGraph conflictGraph=conflictGraphResults.get(flatNode);
2228 // conflictGraph.analyzeConflicts();
2229 conflictGraphResults.put(flatNode, conflictGraph);
2234 private Set<Set> calculateReachabilitySet(OwnershipGraph og,
2235 TempDescriptor tempDescriptor) {
2237 Set<Set> reachabilitySet = new HashSet();
2238 LabelNode ln = og.td2ln.get(tempDescriptor);
2240 Iterator<ReferenceEdge> refEdgeIter = ln.iteratorToReferencees();
2241 while (refEdgeIter.hasNext()) {
2242 ReferenceEdge referenceEdge = (ReferenceEdge) refEdgeIter.next();
2244 ReachabilitySet set = referenceEdge.getBeta();
2245 Iterator<TokenTupleSet> ttsIter = set.iterator();
2246 while (ttsIter.hasNext()) {
2247 TokenTupleSet tokenTupleSet = (TokenTupleSet) ttsIter.next();
2249 HashSet<GloballyUniqueTokenTuple> newTokenTupleSet = new HashSet<GloballyUniqueTokenTuple>();
2250 // reachabilitySet.add(tokenTupleSet);
2252 Iterator iter = tokenTupleSet.iterator();
2253 while (iter.hasNext()) {
2254 TokenTuple tt = (TokenTuple) iter.next();
2255 int token = tt.getToken();
2256 String uniqueID = og.id2hrn.get(new Integer(token))
2257 .getGloballyUniqueIdentifier();
2258 GloballyUniqueTokenTuple gtt = new GloballyUniqueTokenTuple(
2260 newTokenTupleSet.add(gtt);
2263 reachabilitySet.add(newTokenTupleSet);
2268 return reachabilitySet;
2271 private void conflictGraph_nodeAction(MethodContext mc, FlatMethod fm,
2272 FlatNode fn,Hashtable<TempDescriptor, TempDescriptor> invarMap) {
2274 switch (fn.kind()) {
2276 case FKind.FlatSESEEnterNode: {
2278 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
2279 OwnershipGraph og = ownAnalysisForSESEConflicts
2280 .getOwnvershipGraphByMethodContext(mc);
2282 if (!fsen.getIsCallerSESEplaceholder()) {
2283 Set<TempDescriptor> invar_set = fsen.getInVarSet();
2285 SESESummary seseSummary=seseSummaryMap.get(fsen);
2286 ConflictGraph conflictGraph=null;
2287 conflictGraph=conflictGraphResults.get(seseSummary.getCurrentParent());
2289 if(conflictGraph==null){
2290 conflictGraph = new ConflictGraph();
2294 for (Iterator iterator = invar_set.iterator(); iterator
2296 TempDescriptor tempDescriptor = (TempDescriptor) iterator
2299 if(!tempDescriptor.getType().isArray() && tempDescriptor.getType().isImmutable()){
2303 // if(tempDescriptor.getType().isArray()){
2308 SESEEffectsSet seseEffectsSet = fsen.getSeseEffectsSet();
2309 Set<SESEEffectsKey> readEffectsSet = seseEffectsSet
2310 .getReadingSet(tempDescriptor);
2311 Set<SESEEffectsKey> writeEffectsSet = seseEffectsSet
2312 .getWritingSet(tempDescriptor);
2313 Set<SESEEffectsKey> strongUpdateSet = seseEffectsSet.getStrongUpdateSet(tempDescriptor);
2315 Set<Set> reachabilitySet = calculateReachabilitySet(og,
2318 // add new live-in node
2319 // LabelNode ln = og.td2ln.get(tempDescriptor);
2321 OwnershipGraph lastOG = ownAnalysis
2322 .getOwnvershipGraphByMethodContext(mc);
2323 LabelNode ln = lastOG.td2ln.get(tempDescriptor);
2326 Set<HeapRegionNode> hrnSet = new HashSet<HeapRegionNode>();
2327 Iterator<ReferenceEdge> refIter = ln
2328 .iteratorToReferencees();
2329 while (refIter.hasNext()) {
2330 ReferenceEdge referenceEdge = (ReferenceEdge) refIter
2332 hrnSet.add(referenceEdge.getDst());
2335 conflictGraph.addLiveInNode(tempDescriptor, hrnSet, fsen,
2336 readEffectsSet, writeEffectsSet, strongUpdateSet, reachabilitySet);
2340 if(conflictGraph.id2cn.size()>0){
2341 conflictGraphResults.put(seseSummary.getCurrentParent(),conflictGraph);
2354 private void seseConflictsForward(JavaCallGraph javaCallGraph) {
2356 Set methodCallSet = javaCallGraph.getAllMethods(typeUtil.getMain());
2358 // topologically sort java call chain so that leaf calls are ordered
2360 LinkedList<MethodDescriptor> sortedMethodCalls = topologicalSort(
2361 methodCallSet, javaCallGraph);
2363 for (Iterator iterator = sortedMethodCalls.iterator(); iterator
2366 MethodDescriptor md = (MethodDescriptor) iterator.next();
2368 FlatMethod fm = state.getMethodFlat(md);
2370 HashSet<MethodContext> mcSet = ownAnalysis
2371 .getAllMethodContextSetByDescriptor(md);
2372 Iterator<MethodContext> mcIter = mcSet.iterator();
2374 currentMethodSummary = new MethodSummary();
2375 preeffectsSet = new HashSet<PreEffectsKey>();
2377 // iterates over all possible method context
2378 while (mcIter.hasNext()) {
2379 MethodContext mc = mcIter.next();
2381 LinkedList<FlatNode> flatNodesToVisit=new LinkedList<FlatNode>();
2382 flatNodesToVisit.add(fm);
2384 SESESummary summary = new SESESummary(null, fm);
2385 seseSummaryMap.put(fm, summary);
2387 Hashtable<TempDescriptor, TempDescriptor> invarMap=new Hashtable<TempDescriptor,TempDescriptor>();
2389 while (!flatNodesToVisit.isEmpty()) {
2390 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
2391 flatNodesToVisit.remove(fn);
2392 ParentChildConflictsMap prevResult = conflictsResults
2395 // merge sets from control flow
2396 Boolean prevSESE=null;
2397 ParentChildConflictsMap currentConflictsMap = new ParentChildConflictsMap();
2398 for (int i = 0; i < fn.numPrev(); i++) {
2399 FlatNode prevFlatNode = fn.getPrev(i);
2400 ParentChildConflictsMap incoming = conflictsResults
2402 if (incoming != null) {
2403 currentConflictsMap.merge(incoming);
2406 if(prevFlatNode instanceof FlatCondBranch){
2407 prevSESE=isAfterChildSESEIndicatorMap.get(prevFlatNode);
2410 SESESummary currentSummary = seseSummaryMap.get(fn);
2411 //if (currentSummary == null) {
2412 if(!(fn instanceof FlatMethod)){
2413 FlatNode current = null;
2414 FlatNode currentParent = null;
2415 // calculate sese summary info from previous flat nodes
2417 for (int i = 0; i < fn.numPrev(); i++) {
2418 FlatNode prevFlatNode = fn.getPrev(i);
2419 SESESummary prevSummary = seseSummaryMap
2421 if (prevSummary != null) {
2422 if (prevFlatNode instanceof FlatSESEExitNode
2423 && !((FlatSESEExitNode) prevFlatNode)
2425 .getIsCallerSESEplaceholder()) {
2426 current = prevSummary.getCurrentParent();
2427 SESESummary temp = seseSummaryMap
2429 currentParent = temp.getCurrentParent();
2431 current = prevSummary.getCurrentSESE();
2432 currentParent = prevSummary
2433 .getCurrentParent();
2440 currentSummary = new SESESummary(currentParent, current);
2441 seseSummaryMap.put(fn, currentSummary);
2445 if(fn instanceof FlatSESEEnterNode){
2446 isAfterChildSESEIndicatorMap.put(currentSummary.getCurrentSESE(), currentConflictsMap.isAfterSESE());
2448 isAfterChildSESEIndicatorMap.put(currentSummary.getCurrentSESE(), prevSESE);
2452 Boolean b=isAfterChildSESEIndicatorMap.get(currentSummary.getCurrentSESE());;
2454 currentConflictsMap.setIsAfterSESE(false);
2456 currentConflictsMap.setIsAfterSESE(b.booleanValue());
2459 FlatNode tempP=currentSummary.getCurrentParent();
2460 FlatNode tempS=currentSummary.getCurrentSESE();
2462 conflicts_nodeAction(mc, fn, callGraph, preeffectsSet,
2463 currentConflictsMap, currentSummary,invarMap);
2466 // if we have a new result, schedule forward nodes for
2468 if (!currentConflictsMap.equals(prevResult)) {
2469 seseSummaryMap.put(fn, currentSummary);
2470 conflictsResults.put(fn, currentConflictsMap);
2471 for (int i = 0; i < fn.numNext(); i++) {
2472 FlatNode nn = fn.getNext(i);
2473 flatNodesToVisit.addFirst(nn);
2486 private void conflicts_nodeAction(MethodContext mc, FlatNode fn,
2487 CallGraph callGraph, HashSet<PreEffectsKey> preeffectsSet,
2488 ParentChildConflictsMap currentConflictsMap,
2489 SESESummary currentSummary,
2490 Hashtable<TempDescriptor, TempDescriptor> invarMap) {
2492 OwnershipGraph og = ownAnalysis.getOwnvershipGraphByMethodContext(mc);
2494 currentConflictsMap.clearStallMap();
2496 switch (fn.kind()) {
2498 case FKind.FlatSESEEnterNode: {
2500 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
2502 if (!fsen.getIsCallerSESEplaceholder()) {
2503 FlatNode parentNode = currentSummary.getCurrentSESE();
2504 currentSummary.setCurrentParent(parentNode);
2505 currentSummary.setCurrentSESE(fsen);
2506 // seseSummaryMap.put(fsen, currentSummary);
2509 if (!fsen.getIsCallerSESEplaceholder()) {
2510 currentMethodSummary.increaseChildSESECount();
2512 if (currentMethodSummary.getChildSESECount() == 1) {
2513 // need to store pre-effects
2514 currentMethodSummary.getEffectsSet().addAll(preeffectsSet);
2515 for (Iterator iterator = currentMethodSummary.getEffectsSet()
2516 .iterator(); iterator.hasNext();) {
2517 PreEffectsKey preEffectsKey = (PreEffectsKey) iterator
2520 preeffectsSet.clear();
2525 case FKind.FlatSESEExitNode: {
2527 FlatSESEExitNode fsen = (FlatSESEExitNode) fn;
2529 if (!fsen.getFlatEnter().getIsCallerSESEplaceholder()) {
2530 // all object variables are inaccessible.
2531 isAfterChildSESEIndicatorMap.put(currentSummary
2532 .getCurrentParent(), new Boolean(true));
2534 // currentConflictsMap = new ParentChildConflictsMap();
2535 currentConflictsMap.clear();
2540 case FKind.FlatCondBranch: {
2541 boolean isAfterChildSESE = false;
2542 FlatNode current = currentSummary.getCurrentSESE();
2543 Boolean isAfter = isAfterChildSESEIndicatorMap.get(current);
2544 if (isAfter != null && isAfter.booleanValue()) {
2545 isAfterChildSESE = true;
2547 isAfterChildSESEIndicatorMap.put(fn, new Boolean(isAfterChildSESE));
2551 case FKind.FlatNew: {
2553 FlatNew fnew = (FlatNew) fn;
2555 boolean isAfterChildSESE = false;
2556 FlatNode current = currentSummary.getCurrentSESE();
2557 Boolean isAfter = isAfterChildSESEIndicatorMap.get(current);
2558 if (isAfter != null && isAfter.booleanValue()) {
2559 isAfterChildSESE = true;
2562 if (isAfterChildSESE) {
2563 TempDescriptor dst = fnew.getDst();
2564 currentConflictsMap.addAccessibleVar(dst);
2570 case FKind.FlatElementNode:{
2573 FlatElementNode fen = (FlatElementNode) fn;
2574 TempDescriptor src=fen.getSrc();
2576 boolean isAfterChildSESE = false;
2577 FlatNode current = currentSummary.getCurrentSESE();
2578 Boolean isAfter = isAfterChildSESEIndicatorMap.get(current);
2579 if (isAfter != null && isAfter.booleanValue()) {
2580 isAfterChildSESE = true;
2583 if(isAfterChildSESE){
2585 if (!currentConflictsMap.isAccessible(src)) {
2586 if(invarMap.containsKey(src)){
2587 currentConflictsMap.addStallSite(src, new HashSet<HeapRegionNode>(),
2588 new StallTag(fn),invarMap.get(src));
2590 currentConflictsMap.addStallSite(src, new HashSet<HeapRegionNode>(),
2591 new StallTag(fn),null);
2594 currentConflictsMap.addAccessibleVar(src);
2596 // contribute read effect on source's stall site
2597 currentConflictsMap.contributeEffect(src, "", "",
2598 StallSite.READ_EFFECT);
2602 if (currentMethodSummary.getChildSESECount() == 0) {
2603 // analyze preeffects
2604 preEffectAnalysis(og, src, null, PreEffectsKey.READ_EFFECT);
2610 case FKind.FlatFieldNode: {
2612 FlatFieldNode ffn = (FlatFieldNode) fn;
2613 TempDescriptor dst = ffn.getDst();
2614 TempDescriptor src = ffn.getSrc();
2615 FieldDescriptor field = ffn.getField();
2617 boolean isAfterChildSESE = false;
2618 FlatNode current = currentSummary.getCurrentSESE();
2619 Boolean isAfter = isAfterChildSESEIndicatorMap.get(current);
2620 if (isAfter != null && isAfter.booleanValue()) {
2621 isAfterChildSESE = true;
2624 if (isAfterChildSESE) {
2626 if (!currentConflictsMap.isAccessible(src)) {
2627 HashSet<HeapRegionNode> refHRN = getReferenceHeapIDSet(
2629 currentConflictsMap.addStallSite(src, refHRN,
2630 new StallTag(fn),null);
2632 // flag stall site for disjoint analysis
2633 for (Iterator iterator2 = refHRN.iterator(); iterator2
2635 HeapRegionNode hrn = (HeapRegionNode) iterator2
2637 if (hrn.isParameter()) {
2638 // if stall site is paramter heap region, need
2639 // to decompose into caller's
2640 HashSet<HeapRegionNode> visitedHRN = new HashSet<HeapRegionNode>();
2641 visitedHRN.add(hrn);
2642 setupRelatedAllocSiteAnalysis(og, mc, hrn,
2645 flagAllocationSite(mc, hrn.getAllocationSite());
2650 currentConflictsMap.addAccessibleVar(src);
2652 // contribute read effect on source's stall site
2653 currentConflictsMap.contributeEffect(src, field
2654 .getType().getSafeSymbol(), field.getSymbol(),
2655 StallSite.READ_EFFECT);
2657 if(field.getType().isImmutable()){
2658 currentConflictsMap.addAccessibleVar(dst);
2663 if (currentMethodSummary.getChildSESECount() == 0) {
2664 // analyze preeffects
2665 preEffectAnalysis(og, src, field, PreEffectsKey.READ_EFFECT);
2671 case FKind.FlatSetElementNode:{
2673 FlatSetElementNode fsen=(FlatSetElementNode)fn;
2674 TempDescriptor dst = fsen.getDst();
2675 TempDescriptor src = fsen.getSrc();
2677 boolean isAfterChildSESE = false;
2678 FlatNode current = currentSummary.getCurrentSESE();
2679 Boolean isAfter = isAfterChildSESEIndicatorMap.get(current);
2680 if (isAfter != null && isAfter.booleanValue()) {
2681 isAfterChildSESE = true;
2684 if (isAfterChildSESE) {
2686 if (!currentConflictsMap.isAccessible(src)) {
2687 HashSet<HeapRegionNode> refHRN = getReferenceHeapIDSet(og,
2689 currentConflictsMap.addStallSite(src, refHRN , new StallTag(
2692 currentConflictsMap.addAccessibleVar(src);
2694 if (!currentConflictsMap.isAccessible(dst)) {
2696 if(invarMap.containsKey(dst)){
2697 currentConflictsMap.addStallSite(dst, new HashSet<HeapRegionNode>(),
2698 new StallTag(fn),invarMap.get(dst));
2700 currentConflictsMap.addStallSite(dst, new HashSet<HeapRegionNode>(),
2701 new StallTag(fn),null);
2704 currentConflictsMap.addAccessibleVar(dst);
2705 // contribute write effect on destination's stall site
2706 currentConflictsMap.contributeEffect(dst, "","",
2707 StallSite.WRITE_EFFECT);
2711 if (currentMethodSummary.getChildSESECount() == 0) {
2712 // analyze preeffects
2713 preEffectAnalysis(og, dst, null, PreEffectsKey.WRITE_EFFECT);
2717 // if(invarMap.containsKey(dst)){
2718 // System.out.println("THIS IS FLAT SET FIELD:"+dst+ "with sese="+currentSESE);
2719 // TempDescriptor invarTD=invarMap.get(dst);
2720 // currentSESE.getSeseEffectsSet().addWritingVar(invarTD, new SESEEffectsKey("", dst.getType(), new Integer(0), ""));
2726 case FKind.FlatSetFieldNode: {
2728 FlatSetFieldNode fsen = (FlatSetFieldNode) fn;
2729 TempDescriptor dst = fsen.getDst();
2730 FieldDescriptor field = fsen.getField();
2731 TempDescriptor src = fsen.getSrc();
2733 boolean isAfterChildSESE = false;
2734 FlatNode current = currentSummary.getCurrentSESE();
2735 Boolean isAfter = isAfterChildSESEIndicatorMap.get(current);
2736 if (isAfter != null && isAfter.booleanValue()) {
2737 isAfterChildSESE = true;
2740 if (isAfterChildSESE) {
2742 if (!currentConflictsMap.isAccessible(src)) {
2743 HashSet<HeapRegionNode> refHRN = getReferenceHeapIDSet(og,
2745 currentConflictsMap.addStallSite(src, refHRN, new StallTag(
2748 // flag stall site for disjoint analysis
2749 for (Iterator iterator2 = refHRN.iterator(); iterator2
2751 HeapRegionNode hrn = (HeapRegionNode) iterator2.next();
2753 if (hrn.isParameter()) {
2754 // if stall site is paramter heap region, need
2755 // to decompose into caller's
2756 HashSet<HeapRegionNode> visitedHRN = new HashSet<HeapRegionNode>();
2757 visitedHRN.add(hrn);
2758 setupRelatedAllocSiteAnalysis(og, mc, hrn,
2761 flagAllocationSite(mc, hrn.getAllocationSite());
2767 currentConflictsMap.addAccessibleVar(src);
2770 if (!currentConflictsMap.isAccessible(dst)) {
2771 HashSet<HeapRegionNode> refHRN = getReferenceHeapIDSet(
2773 currentConflictsMap.addStallSite(dst, refHRN,
2774 new StallTag(fn),null);
2776 // flag stall site for disjoint analysis
2777 for (Iterator iterator2 = refHRN.iterator(); iterator2
2779 HeapRegionNode hrn = (HeapRegionNode) iterator2
2781 if (hrn.isParameter()) {
2782 // if stall site is paramter heap region, need
2783 // to decompose into caller's
2784 HashSet<HeapRegionNode> visitedHRN = new HashSet<HeapRegionNode>();
2785 visitedHRN.add(hrn);
2786 setupRelatedAllocSiteAnalysis(og, mc, hrn,
2789 flagAllocationSite(mc, hrn.getAllocationSite());
2794 currentConflictsMap.addAccessibleVar(dst);
2795 // contribute write effect on destination's stall site
2796 currentConflictsMap.contributeEffect(dst, field
2797 .getType().getSafeSymbol(), field.getSymbol(),
2798 StallSite.WRITE_EFFECT);
2801 // TODO need to create edge mapping for newly created edge
2802 HashSet<ReferenceEdge> edges = getRefEdgeSetReferenceToSameHRN(
2805 StallSite ss = currentConflictsMap.getStallMap().get(dst);
2807 for (Iterator iterator = edges.iterator(); iterator
2809 ReferenceEdge referenceEdge = (ReferenceEdge) iterator
2811 if (!(referenceEdge.getSrc() instanceof LabelNode)) {
2812 currentConflictsMap.addStallEdge(referenceEdge,
2819 if (currentMethodSummary.getChildSESECount() == 0) {
2820 // analyze preeffects
2821 preEffectAnalysis(og, dst, field, PreEffectsKey.WRITE_EFFECT);
2827 case FKind.FlatOpNode: {
2829 FlatOpNode fon = (FlatOpNode) fn;
2831 boolean isAfterChildSESE = false;
2832 FlatNode current = currentSummary.getCurrentSESE();
2833 Boolean isAfter = isAfterChildSESEIndicatorMap.get(current);
2836 if( fon.getOp().getOp() ==Operation.ASSIGN){
2837 invarMap.put(fon.getDest(), fon.getLeft());
2840 if (isAfter != null && isAfter.booleanValue()) {
2841 isAfterChildSESE = true;
2844 if (isAfterChildSESE) {
2846 // destination variable gets the status of source.
2848 if (fon.getOp().getOp() == Operation.ASSIGN) {
2850 TempDescriptor dst = fon.getDest();
2851 TempDescriptor src = fon.getLeft();
2853 Integer sourceStatus = currentConflictsMap
2854 .getAccessibleMap().get(src);
2855 if (sourceStatus == null) {
2856 sourceStatus = ParentChildConflictsMap.INACCESSIBLE;
2859 HashSet<TempDescriptor> dstTempSet = getTempDescSetReferenceToSameHRN(
2862 for (Iterator<TempDescriptor> iterator = dstTempSet
2863 .iterator(); iterator.hasNext();) {
2864 TempDescriptor possibleDst = iterator.next();
2867 .equals(ParentChildConflictsMap.ACCESSIBLE)) {
2868 currentConflictsMap.addAccessibleVar(possibleDst);
2870 currentConflictsMap.addInaccessibleVar(possibleDst);
2881 case FKind.FlatCall: {
2883 FlatCall fc = (FlatCall) fn;
2885 boolean isAfterChildSESE = false;
2886 FlatNode current = currentSummary.getCurrentSESE();
2887 Boolean isAfter = isAfterChildSESEIndicatorMap.get(current);
2888 if (isAfter != null && isAfter.booleanValue()) {
2889 isAfterChildSESE = true;
2893 if (!fc.getMethod().isStatic()) {
2897 FlatMethod calleeFM = state.getMethodFlat(fc.getMethod());
2899 // retrieve callee's method summary
2900 MethodSummary calleeMethodSummary = methodSummaryResults
2903 if (calleeMethodSummary != null
2904 && calleeMethodSummary.getChildSESECount() > 0) {
2906 // when parameter variable is accessible,
2907 // use callee's preeffects to figure out about how it affects
2908 // caller's stall site
2910 for (int i = 0; i < fc.numArgs(); i++) {
2911 TempDescriptor paramTemp = fc.getArg(i);
2913 if (isAfterChildSESE) {
2914 if (currentConflictsMap.isAccessible(paramTemp)
2915 && currentConflictsMap.hasStallSite(paramTemp)) {
2916 // preeffect contribute its effect to caller's stall
2920 if (!fc.getMethod().isStatic()) {
2924 HashSet<PreEffectsKey> preeffectSet = calleeMethodSummary
2925 .getEffectsSetByParamIdx(i + offset);
2927 for (Iterator iterator = preeffectSet.iterator(); iterator
2929 PreEffectsKey preEffectsKey = (PreEffectsKey) iterator
2931 currentConflictsMap.contributeEffect(paramTemp,
2932 preEffectsKey.getType(), preEffectsKey
2933 .getField(), preEffectsKey
2938 // in other cases, child SESE has not been discovered,
2939 // assumes that all variables are accessible
2943 // If callee has at least one child sese, all parent object
2944 // is going to be inaccessible.
2945 // currentConflictsMap = new ParentChildConflictsMap();
2946 currentConflictsMap.makeAllInaccessible();
2947 isAfterChildSESEIndicatorMap.put(currentSummary
2948 .getCurrentSESE(), new Boolean(true));
2950 TempDescriptor returnTemp = fc.getReturnTemp();
2952 if (calleeMethodSummary.getReturnValueAccessibility().equals(
2953 MethodSummary.ACCESSIBLE)) {
2954 // when return value is accessible, associate with its
2956 currentConflictsMap.addAccessibleVar(returnTemp);
2958 StallSite returnStallSite = calleeMethodSummary
2959 .getReturnStallSite().copy();
2960 // handling parameter regions
2961 HashSet<Integer> stallParamIdx = returnStallSite
2962 .getCallerParamIdxSet();
2963 for (Iterator iterator = stallParamIdx.iterator(); iterator
2965 Integer idx = (Integer) iterator.next();
2967 int paramIdx = idx.intValue() - base;
2968 TempDescriptor paramTD = fc.getArg(paramIdx);
2970 // TODO: resolve callee's parameter heap regions by
2971 // following call chain
2975 // flag stall site's allocation sites for disjointness
2977 HashSet<HeapRegionNode> hrnSet = returnStallSite
2979 for (Iterator iterator = hrnSet.iterator(); iterator
2981 HeapRegionNode hrn = (HeapRegionNode) iterator.next();
2982 if (hrn.isParameter()) {
2983 // if stall site is paramter heap region, need to
2984 // decompose into caller's
2985 HashSet<HeapRegionNode> visitedHRN = new HashSet<HeapRegionNode>();
2986 visitedHRN.add(hrn);
2987 setupRelatedAllocSiteAnalysis(og, mc, hrn,
2990 flagAllocationSite(mc, hrn.getAllocationSite());
2994 currentConflictsMap.addStallSite(returnTemp,
2997 } else if (calleeMethodSummary.getReturnValueAccessibility()
2998 .equals(MethodSummary.INACCESSIBLE)) {
2999 // when return value is inaccessible
3000 currentConflictsMap.addInaccessibleVar(returnTemp);
3003 // TODO: need to handle edge mappings from callee
3004 Set<Integer> stallParamIdx = calleeMethodSummary
3005 .getStallParamIdxSet();
3006 for (Iterator iterator = stallParamIdx.iterator(); iterator
3008 Integer paramIdx = (Integer) iterator.next();
3009 HashSet<StallTag> stallTagSet = calleeMethodSummary
3010 .getStallTagByParamIdx(paramIdx);
3012 int argIdx = paramIdx.intValue() - base;
3013 TempDescriptor argTD = fc.getArg(argIdx);
3015 putStallTagOnReferenceEdges(og, argTD, stallTagSet,
3016 currentConflictsMap);
3024 * do we need this case? case FKind.FlatLiteralNode: {
3026 * if (currentConflictsMap.isAfterChildSESE()) { FlatLiteralNode fln =
3027 * (FlatLiteralNode) fn; TempDescriptor dst = fln.getDst();
3028 * currentConflictsMap.addAccessibleVar(dst); }
3033 case FKind.FlatReturnNode: {
3035 FlatReturnNode frn = (FlatReturnNode) fn;
3036 TempDescriptor returnTD = frn.getReturnTemp();
3038 boolean isAfterChildSESE = false;
3039 FlatNode current = currentSummary.getCurrentSESE();
3040 Boolean isAfter = isAfterChildSESEIndicatorMap.get(current);
3041 if (isAfter != null && isAfter.booleanValue()) {
3042 isAfterChildSESE = true;
3045 if (returnTD != null) {
3046 if (!isAfterChildSESE) {
3047 // in this case, all variables are accessible. There are no
3050 if (currentConflictsMap.isAccessible(returnTD)) {
3052 currentMethodSummary
3053 .setReturnValueAccessibility(MethodSummary.ACCESSIBLE);
3054 StallSite returnStallSite = currentConflictsMap
3055 .getStallMap().get(returnTD);
3057 HashSet<HeapRegionNode> stallSiteHRNSet = returnStallSite
3059 for (Iterator iterator = stallSiteHRNSet.iterator(); iterator
3061 HeapRegionNode stallSiteHRN = (HeapRegionNode) iterator
3063 Set<Integer> paramSet = og.idPrimary2paramIndexSet
3064 .get(stallSiteHRN.getID());
3065 returnStallSite.addCallerParamIdxSet(paramSet);
3066 paramSet = og.idSecondary2paramIndexSet
3067 .get(stallSiteHRN.getID());
3068 returnStallSite.addCallerParamIdxSet(paramSet);
3071 currentMethodSummary
3072 .setReturnStallSite(returnStallSite);
3075 currentMethodSummary
3076 .setReturnValueAccessibility(MethodSummary.INACCESSIBLE);
3083 case FKind.FlatExit: {
3085 // store method summary when it has at least one child SESE
3086 if (currentMethodSummary.getChildSESECount() > 0) {
3087 // current flat method
3088 FlatMethod fm = state.getMethodFlat(mc.getDescriptor());
3089 Set<TempDescriptor> stallTempSet = currentConflictsMap
3090 .getStallMap().keySet();
3091 for (Iterator iterator = stallTempSet.iterator(); iterator
3093 TempDescriptor stallTD = (TempDescriptor) iterator.next();
3094 StallSite stallSite = currentConflictsMap.getStallMap()
3097 HashSet<HeapRegionNode> stallSiteHRNSet = stallSite
3099 for (Iterator iterator2 = stallSiteHRNSet.iterator(); iterator2
3101 HeapRegionNode stallSiteHRN = (HeapRegionNode) iterator2
3104 if (stallSiteHRN.isParameter()) {
3106 Set<Integer> paramSet = og.idPrimary2paramIndexSet
3107 .get(stallSiteHRN.getID());
3108 currentMethodSummary.addStallParamIdxSet(paramSet,
3109 stallSite.getStallTagSet());
3111 paramSet = og.idSecondary2paramIndexSet
3112 .get(stallSiteHRN.getID());
3113 currentMethodSummary.addStallParamIdxSet(paramSet,
3114 stallSite.getStallTagSet());
3120 methodSummaryResults.put(fm, currentMethodSummary);
3127 // seseSummaryMap.put(fn, currentSummary);
3131 private void putStallTagOnReferenceEdges(OwnershipGraph og,
3132 TempDescriptor argTD, HashSet stallTagSet,
3133 ParentChildConflictsMap currentConflictsMap) {
3135 LabelNode ln=og.td2ln.get(argTD);
3138 Iterator<ReferenceEdge> refrenceeIter=ln.iteratorToReferencees();
3139 while (refrenceeIter.hasNext()) {
3140 ReferenceEdge refEdge = (ReferenceEdge) refrenceeIter.next();
3141 HeapRegionNode stallHRN=refEdge.getDst();
3143 Iterator<ReferenceEdge> referencerIter=stallHRN.iteratorToReferencers();
3144 while (referencerIter.hasNext()) {
3145 ReferenceEdge referencer = (ReferenceEdge) referencerIter
3147 for (Iterator iterator = stallTagSet.iterator(); iterator
3149 StallTag stallTag = (StallTag) iterator.next();
3150 currentConflictsMap.addStallEdge(referencer, stallTag);
3157 private void preEffectAnalysis(OwnershipGraph og, TempDescriptor td,
3158 FieldDescriptor field, Integer effectType) {
3160 // analyze preeffects
3161 HashSet<HeapRegionNode> hrnSet = getReferenceHeapIDSet(og, td);
3162 for (Iterator iterator = hrnSet.iterator(); iterator.hasNext();) {
3163 HeapRegionNode hrn = (HeapRegionNode) iterator.next();
3164 if (hrn.isParameter()) {
3165 // effects on param heap region
3167 Set<Integer> paramSet = og.idPrimary2paramIndexSet.get(hrn
3170 if (paramSet != null) {
3171 Iterator<Integer> paramIter = paramSet.iterator();
3172 while (paramIter.hasNext()) {
3173 Integer paramID = paramIter.next();
3174 PreEffectsKey effectKey=null;
3176 effectKey = new PreEffectsKey(paramID,
3177 field.getSymbol(), field.getType()
3178 .getSafeSymbol(), effectType);
3180 effectKey = new PreEffectsKey(paramID,
3181 "", "", effectType);
3183 preeffectsSet.add(effectKey);
3187 // check weather this heap region is parameter
3190 paramSet = og.idSecondary2paramIndexSet.get(hrn.getID());
3191 if (paramSet != null) {
3192 Iterator<Integer> paramIter = paramSet.iterator();
3194 while (paramIter.hasNext()) {
3195 Integer paramID = paramIter.next();
3196 PreEffectsKey effectKey=null;
3198 effectKey = new PreEffectsKey(paramID,
3199 field.getSymbol(), field.getType()
3200 .getSafeSymbol(), effectType);
3202 effectKey = new PreEffectsKey(paramID,
3203 "", "", effectType);
3205 preeffectsSet.add(effectKey);
3213 private void codePlansForward( FlatMethod fm ) {
3215 // start from flat method top, visit every node in
3216 // method exactly once
3217 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
3218 flatNodesToVisit.add( fm );
3220 Set<FlatNode> visited = new HashSet<FlatNode>();
3222 while( !flatNodesToVisit.isEmpty() ) {
3223 Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
3224 FlatNode fn = fnItr.next();
3226 flatNodesToVisit.remove( fn );
3229 Stack<FlatSESEEnterNode> seseStack = seseStacks.get( fn );
3230 assert seseStack != null;
3232 // use incoming results as "dot statement" or just
3233 // before the current statement
3234 VarSrcTokTable dotSTtable = new VarSrcTokTable();
3235 for( int i = 0; i < fn.numPrev(); i++ ) {
3236 FlatNode nn = fn.getPrev( i );
3237 dotSTtable.merge( variableResults.get( nn ) );
3240 // find dt-st notAvailableSet also
3241 Set<TempDescriptor> dotSTnotAvailSet = new HashSet<TempDescriptor>();
3242 for( int i = 0; i < fn.numPrev(); i++ ) {
3243 FlatNode nn = fn.getPrev( i );
3244 Set<TempDescriptor> notAvailIn = notAvailableResults.get( nn );
3245 if( notAvailIn != null ) {
3246 dotSTnotAvailSet.addAll( notAvailIn );
3250 Set<TempDescriptor> dotSTlive = livenessRootView.get( fn );
3252 if( !seseStack.empty() ) {
3253 codePlans_nodeActions( fn,
3261 for( int i = 0; i < fn.numNext(); i++ ) {
3262 FlatNode nn = fn.getNext( i );
3264 if( !visited.contains( nn ) ) {
3265 flatNodesToVisit.add( nn );
3271 private void codePlans_nodeActions( FlatNode fn,
3272 Set<TempDescriptor> liveSetIn,
3273 VarSrcTokTable vstTableIn,
3274 Set<TempDescriptor> notAvailSetIn,
3275 FlatSESEEnterNode currentSESE ) {
3277 CodePlan plan = new CodePlan( currentSESE);
3279 switch( fn.kind() ) {
3281 case FKind.FlatSESEEnterNode: {
3282 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
3283 assert fsen.equals( currentSESE );
3285 // track the source types of the in-var set so generated
3286 // code at this SESE issue can compute the number of
3287 // dependencies properly
3288 Iterator<TempDescriptor> inVarItr = fsen.getInVarSet().iterator();
3289 while( inVarItr.hasNext() ) {
3290 TempDescriptor inVar = inVarItr.next();
3292 // when we get to an SESE enter node we change the
3293 // currentSESE variable of this analysis to the
3294 // child that is declared by the enter node, so
3295 // in order to classify in-vars correctly, pass
3296 // the parent SESE in--at other FlatNode types just
3297 // use the currentSESE
3298 VSTWrapper vstIfStatic = new VSTWrapper();
3300 vstTableIn.getRefVarSrcType( inVar,
3305 // the current SESE needs a local space to track the dynamic
3306 // variable and the child needs space in its SESE record
3307 if( srcType.equals( VarSrcTokTable.SrcType_DYNAMIC ) ) {
3308 fsen.addDynamicInVar( inVar );
3309 fsen.getParent().addDynamicVar( inVar );
3311 } else if( srcType.equals( VarSrcTokTable.SrcType_STATIC ) ) {
3312 fsen.addStaticInVar( inVar );
3313 VariableSourceToken vst = vstIfStatic.vst;
3314 fsen.putStaticInVar2src( inVar, vst );
3315 fsen.addStaticInVarSrc( new SESEandAgePair( vst.getSESE(),
3320 assert srcType.equals( VarSrcTokTable.SrcType_READY );
3321 fsen.addReadyInVar( inVar );
3327 case FKind.FlatSESEExitNode: {
3328 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
3331 case FKind.FlatOpNode: {
3332 FlatOpNode fon = (FlatOpNode) fn;
3334 if( fon.getOp().getOp() == Operation.ASSIGN ) {
3335 TempDescriptor lhs = fon.getDest();
3336 TempDescriptor rhs = fon.getLeft();
3338 // if this is an op node, don't stall, copy
3339 // source and delay until we need to use value
3341 // ask whether lhs and rhs sources are dynamic, static, etc.
3342 VSTWrapper vstIfStatic = new VSTWrapper();
3344 = vstTableIn.getRefVarSrcType( lhs,
3349 = vstTableIn.getRefVarSrcType( rhs,
3354 if( rhsSrcType.equals( VarSrcTokTable.SrcType_DYNAMIC ) ) {
3355 // if rhs is dynamic going in, lhs will definitely be dynamic
3356 // going out of this node, so track that here
3357 plan.addDynAssign( lhs, rhs );
3358 currentSESE.addDynamicVar( lhs );
3359 currentSESE.addDynamicVar( rhs );
3361 } else if( lhsSrcType.equals( VarSrcTokTable.SrcType_DYNAMIC ) ) {
3362 // otherwise, if the lhs is dynamic, but the rhs is not, we
3363 // need to update the variable's dynamic source as "current SESE"
3364 plan.addDynAssign( lhs );
3367 // only break if this is an ASSIGN op node,
3368 // otherwise fall through to default case
3373 // note that FlatOpNode's that aren't ASSIGN
3374 // fall through to this default case
3377 // a node with no live set has nothing to stall for
3378 if( liveSetIn == null ) {
3382 TempDescriptor[] readarray = fn.readsTemps();
3383 for( int i = 0; i < readarray.length; i++ ) {
3384 TempDescriptor readtmp = readarray[i];
3386 // ignore temps that are definitely available
3387 // when considering to stall on it
3388 if( !notAvailSetIn.contains( readtmp ) ) {
3392 // check the source type of this variable
3393 VSTWrapper vstIfStatic = new VSTWrapper();
3395 = vstTableIn.getRefVarSrcType( readtmp,
3400 if( srcType.equals( VarSrcTokTable.SrcType_DYNAMIC ) ) {
3401 // 1) It is not clear statically where this variable will
3402 // come from, so dynamically we must keep track
3403 // along various control paths, and therefore when we stall,
3404 // just stall for the exact thing we need and move on
3405 plan.addDynamicStall( readtmp );
3406 currentSESE.addDynamicVar( readtmp );
3408 } else if( srcType.equals( VarSrcTokTable.SrcType_STATIC ) ) {
3409 // 2) Single token/age pair: Stall for token/age pair, and copy
3410 // all live variables with same token/age pair at the same
3411 // time. This is the same stuff that the notavaialable analysis
3412 // marks as now available.
3413 VariableSourceToken vst = vstIfStatic.vst;
3415 Iterator<VariableSourceToken> availItr =
3416 vstTableIn.get( vst.getSESE(), vst.getAge() ).iterator();
3418 while( availItr.hasNext() ) {
3419 VariableSourceToken vstAlsoAvail = availItr.next();
3421 // only grab additional stuff that is live
3422 Set<TempDescriptor> copySet = new HashSet<TempDescriptor>();
3424 Iterator<TempDescriptor> refVarItr = vstAlsoAvail.getRefVars().iterator();
3425 while( refVarItr.hasNext() ) {
3426 TempDescriptor refVar = refVarItr.next();
3427 if( liveSetIn.contains( refVar ) ) {
3428 copySet.add( refVar );
3432 if( !copySet.isEmpty() ) {
3433 plan.addStall2CopySet( vstAlsoAvail, copySet );
3438 // the other case for srcs is READY, so do nothing
3441 // assert that everything being stalled for is in the
3442 // "not available" set coming into this flat node and
3443 // that every VST identified is in the possible "stall set"
3444 // that represents VST's from children SESE's
3452 // identify sese-age pairs that are statically useful
3453 // and should have an associated SESE variable in code
3454 // JUST GET ALL SESE/AGE NAMES FOR NOW, PRUNE LATER,
3455 // AND ALWAYS GIVE NAMES TO PARENTS
3456 Set<VariableSourceToken> staticSet = vstTableIn.get();
3457 Iterator<VariableSourceToken> vstItr = staticSet.iterator();
3458 while( vstItr.hasNext() ) {
3459 VariableSourceToken vst = vstItr.next();
3461 // placeholder source tokens are useful results, but
3462 // the placeholder static name is never needed
3463 if( vst.getSESE().getIsCallerSESEplaceholder() ) {
3467 FlatSESEEnterNode sese = currentSESE;
3468 while( sese != null ) {
3469 sese.addNeededStaticName(
3470 new SESEandAgePair( vst.getSESE(), vst.getAge() )
3472 sese.mustTrackAtLeastAge( vst.getAge() );
3474 sese = sese.getParent();
3479 codePlans.put( fn, plan );
3482 // if any variables at this-node-*dot* have a static source (exactly one vst)
3483 // but go to a dynamic source at next-node-*dot*, create a new IR graph
3484 // node on that edge to track the sources dynamically
3485 VarSrcTokTable thisVstTable = variableResults.get( fn );
3486 for( int i = 0; i < fn.numNext(); i++ ) {
3487 FlatNode nn = fn.getNext( i );
3488 VarSrcTokTable nextVstTable = variableResults.get( nn );
3489 Set<TempDescriptor> nextLiveIn = livenessRootView.get( nn );
3491 // the table can be null if it is one of the few IR nodes
3492 // completely outside of the root SESE scope
3493 if( nextVstTable != null && nextLiveIn != null ) {
3495 Hashtable<TempDescriptor, VSTWrapper> readyOrStatic2dynamicSet =
3496 thisVstTable.getReadyOrStatic2DynamicSet( nextVstTable,
3501 if( !readyOrStatic2dynamicSet.isEmpty() ) {
3503 // either add these results to partial fixed-point result
3504 // or make a new one if we haven't made any here yet
3505 FlatEdge fe = new FlatEdge( fn, nn );
3506 FlatWriteDynamicVarNode fwdvn = wdvNodesToSpliceIn.get( fe );
3508 if( fwdvn == null ) {
3509 fwdvn = new FlatWriteDynamicVarNode( fn,
3511 readyOrStatic2dynamicSet,
3514 wdvNodesToSpliceIn.put( fe, fwdvn );
3516 fwdvn.addMoreVar2Src( readyOrStatic2dynamicSet );
3524 public void writeReports( String timeReport ) throws java.io.IOException {
3526 BufferedWriter bw = new BufferedWriter( new FileWriter( "mlpReport_summary.txt" ) );
3527 bw.write( "MLP Analysis Results\n\n" );
3528 bw.write( timeReport+"\n\n" );
3529 printSESEHierarchy( bw );
3531 printSESEInfo( bw );
3534 Iterator<Descriptor> methItr = ownAnalysis.descriptorsToAnalyze.iterator();
3535 while( methItr.hasNext() ) {
3536 MethodDescriptor md = (MethodDescriptor) methItr.next();
3537 FlatMethod fm = state.getMethodFlat( md );
3538 bw = new BufferedWriter( new FileWriter( "mlpReport_"+
3539 md.getClassMethodName()+
3540 md.getSafeMethodDescriptor()+
3542 bw.write( "MLP Results for "+md+"\n-------------------\n");
3544 FlatSESEEnterNode implicitSESE = (FlatSESEEnterNode) fm.getNext(0);
3545 if( !implicitSESE.getIsCallerSESEplaceholder() &&
3546 implicitSESE != mainSESE
3548 System.out.println( implicitSESE+" is not implicit?!" );
3551 bw.write( "Dynamic vars to manage:\n "+implicitSESE.getDynamicVarSet());
3553 bw.write( "\n\nLive-In, Root View\n------------------\n" +fm.printMethod( livenessRootView ) );
3554 bw.write( "\n\nVariable Results-Out\n----------------\n" +fm.printMethod( variableResults ) );
3555 bw.write( "\n\nNot Available Results-Out\n---------------------\n"+fm.printMethod( notAvailableResults ) );
3556 bw.write( "\n\nCode Plans\n----------\n" +fm.printMethod( codePlans ) );
3557 bw.write("\n\nSESE Effects\n----------------------\n"+printSESEEffects());
3562 private String printSESEEffects() {
3564 StringWriter writer = new StringWriter();
3566 Iterator<FlatSESEEnterNode> keyIter = allSESEs.iterator();
3568 while (keyIter.hasNext()) {
3569 FlatSESEEnterNode seseEnter = keyIter.next();
3570 String result = seseEnter.getSeseEffectsSet().printSet();
3571 if (result.length() > 0) {
3572 writer.write("\nSESE " + seseEnter + "\n");
3573 writer.write(result);
3576 keyIter = rootSESEs.iterator();
3577 while (keyIter.hasNext()) {
3578 FlatSESEEnterNode seseEnter = keyIter.next();
3579 if (seseEnter.getIsCallerSESEplaceholder()) {
3580 if (!seseEnter.getChildren().isEmpty()) {
3581 String result = seseEnter.getSeseEffectsSet().printSet();
3582 if (result.length() > 0) {
3583 writer.write("\nSESE " + seseEnter + "\n");
3584 writer.write(result);
3590 return writer.toString();
3594 private void printSESEHierarchy( BufferedWriter bw ) throws java.io.IOException {
3595 bw.write( "SESE Hierarchy\n--------------\n" );
3596 Iterator<FlatSESEEnterNode> rootItr = rootSESEs.iterator();
3597 while( rootItr.hasNext() ) {
3598 FlatSESEEnterNode root = rootItr.next();
3599 if( root.getIsCallerSESEplaceholder() ) {
3600 if( !root.getChildren().isEmpty() ) {
3601 printSESEHierarchyTree( bw, root, 0 );
3604 printSESEHierarchyTree( bw, root, 0 );
3609 private void printSESEHierarchyTree( BufferedWriter bw,
3610 FlatSESEEnterNode fsen,
3612 ) throws java.io.IOException {
3613 for( int i = 0; i < depth; ++i ) {
3616 bw.write( "- "+fsen.getPrettyIdentifier()+"\n" );
3618 Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
3619 while( childItr.hasNext() ) {
3620 FlatSESEEnterNode fsenChild = childItr.next();
3621 printSESEHierarchyTree( bw, fsenChild, depth + 1 );
3626 private void printSESEInfo( BufferedWriter bw ) throws java.io.IOException {
3627 bw.write("\nSESE info\n-------------\n" );
3628 Iterator<FlatSESEEnterNode> rootItr = rootSESEs.iterator();
3629 while( rootItr.hasNext() ) {
3630 FlatSESEEnterNode root = rootItr.next();
3631 if( root.getIsCallerSESEplaceholder() ) {
3632 if( !root.getChildren().isEmpty() ) {
3633 printSESEInfoTree( bw, root );
3636 printSESEInfoTree( bw, root );
3641 private void printSESEInfoTree( BufferedWriter bw,
3642 FlatSESEEnterNode fsen
3643 ) throws java.io.IOException {
3645 if( !fsen.getIsCallerSESEplaceholder() ) {
3646 bw.write( "SESE "+fsen.getPrettyIdentifier()+" {\n" );
3648 bw.write( " in-set: "+fsen.getInVarSet()+"\n" );
3649 Iterator<TempDescriptor> tItr = fsen.getInVarSet().iterator();
3650 while( tItr.hasNext() ) {
3651 TempDescriptor inVar = tItr.next();
3652 if( fsen.getReadyInVarSet().contains( inVar ) ) {
3653 bw.write( " (ready) "+inVar+"\n" );
3655 if( fsen.getStaticInVarSet().contains( inVar ) ) {
3656 bw.write( " (static) "+inVar+" from "+
3657 fsen.getStaticInVarSrc( inVar )+"\n" );
3659 if( fsen.getDynamicInVarSet().contains( inVar ) ) {
3660 bw.write( " (dynamic)"+inVar+"\n" );
3664 bw.write( " Dynamic vars to manage: "+fsen.getDynamicVarSet()+"\n");
3666 bw.write( " out-set: "+fsen.getOutVarSet()+"\n" );
3670 Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
3671 while( childItr.hasNext() ) {
3672 FlatSESEEnterNode fsenChild = childItr.next();
3673 printSESEInfoTree( bw, fsenChild );
3677 public Hashtable <FlatNode, ConflictGraph> getConflictGraphResults(){
3678 return conflictGraphResults;
3681 public Hashtable < FlatNode, ParentChildConflictsMap > getConflictsResults(){
3682 return conflictsResults;
3685 public Hashtable<FlatNode, SESESummary> getSeseSummaryMap(){
3686 return seseSummaryMap;
3689 public Hashtable<ConflictGraph, HashSet<SESELock>> getConflictGraphLockMap(){
3690 return conflictGraphLockMap;