1 package Analysis.OoOJava;
3 import java.io.BufferedWriter;
4 import java.io.FileWriter;
5 import java.io.IOException;
6 import java.util.Enumeration;
7 import java.util.HashSet;
8 import java.util.Hashtable;
9 import java.util.Iterator;
12 import java.util.Stack;
13 import java.util.Map.Entry;
15 import Analysis.ArrayReferencees;
16 import Analysis.Liveness;
17 import Analysis.CallGraph.CallGraph;
18 import Analysis.Disjoint.DisjointAnalysis;
19 import Analysis.Disjoint.Effect;
20 import Analysis.Disjoint.EffectsAnalysis;
21 import Analysis.Disjoint.Taint;
23 import IR.MethodDescriptor;
28 import IR.Flat.FlatCall;
29 import IR.Flat.FlatEdge;
30 import IR.Flat.FlatElementNode;
31 import IR.Flat.FlatFieldNode;
32 import IR.Flat.FlatMethod;
33 import IR.Flat.FlatNew;
34 import IR.Flat.FlatNode;
35 import IR.Flat.FlatOpNode;
36 import IR.Flat.FlatSESEEnterNode;
37 import IR.Flat.FlatSESEExitNode;
38 import IR.Flat.FlatSetElementNode;
39 import IR.Flat.FlatSetFieldNode;
40 import IR.Flat.FlatWriteDynamicVarNode;
41 import IR.Flat.TempDescriptor;
43 public class OoOJavaAnalysis {
45 // data from the compiler
47 private TypeUtil typeUtil;
48 private CallGraph callGraph;
49 private RBlockRelationAnalysis rblockRel;
50 private DisjointAnalysis disjointAnalysisTaints;
51 private DisjointAnalysis disjointAnalysisReach;
53 private Set<MethodDescriptor> descriptorsToAnalyze;
55 private Hashtable<FlatNode, Set<TempDescriptor>> livenessGlobalView;
56 private Hashtable<FlatNode, Set<TempDescriptor>> livenessVirtualReads;
57 private Hashtable<FlatNode, VarSrcTokTable> variableResults;
58 private Hashtable<FlatNode, Set<TempDescriptor>> notAvailableResults;
59 private Hashtable<FlatNode, CodePlan> codePlans;
61 private Hashtable<FlatSESEEnterNode, Set<TempDescriptor>> notAvailableIntoSESE;
63 private Hashtable<FlatEdge, FlatWriteDynamicVarNode> wdvNodesToSpliceIn;
65 // temporal data structures to track analysis progress.
66 static private int uniqueLockSetId = 0;
67 // mapping of a conflict graph to its compiled lock
68 private Hashtable<ConflictGraph, HashSet<SESELock>> conflictGraph2SESELock;
69 // mapping of a sese block to its conflict graph
70 private Hashtable<FlatNode, ConflictGraph> sese2conflictGraph;
72 public static int maxSESEage = -1;
74 public int getMaxSESEage() {
79 public CodePlan getCodePlan(FlatNode fn) {
80 CodePlan cp = codePlans.get(fn);
84 public Set<FlatNode> getNodesWithPlans() {
85 return codePlans.keySet();
88 public DisjointAnalysis getDisjointAnalysis() {
89 return disjointAnalysisTaints;
93 public OoOJavaAnalysis(State state,
97 ArrayReferencees arrayReferencees) {
99 double timeStartAnalysis = (double) System.nanoTime();
102 this.typeUtil = typeUtil;
103 this.callGraph = callGraph;
104 this.maxSESEage = state.OOO_MAXSESEAGE;
106 livenessGlobalView = new Hashtable<FlatNode, Set<TempDescriptor>>();
107 livenessVirtualReads = new Hashtable<FlatNode, Set<TempDescriptor>>();
108 variableResults = new Hashtable<FlatNode, VarSrcTokTable>();
109 notAvailableResults = new Hashtable<FlatNode, Set<TempDescriptor>>();
110 codePlans = new Hashtable<FlatNode, CodePlan>();
111 wdvNodesToSpliceIn = new Hashtable<FlatEdge, FlatWriteDynamicVarNode>();
112 notAvailableIntoSESE = new Hashtable<FlatSESEEnterNode, Set<TempDescriptor>>();
113 sese2conflictGraph = new Hashtable<FlatNode, ConflictGraph>();
114 conflictGraph2SESELock = new Hashtable<ConflictGraph, HashSet<SESELock>>();
116 // add all methods transitively reachable from the
117 // source's main to set for analysis
118 MethodDescriptor mdSourceEntry = typeUtil.getMain();
119 FlatMethod fmMain = state.getMethodFlat(mdSourceEntry);
121 descriptorsToAnalyze = callGraph.getAllMethods(mdSourceEntry);
123 descriptorsToAnalyze.add(mdSourceEntry);
125 // 1st pass, find basic rblock relations & potential stall sites
126 rblockRel = new RBlockRelationAnalysis(state, typeUtil, callGraph);
127 VarSrcTokTable.rblockRel = rblockRel;
129 // 2nd pass, liveness, in-set out-set (no virtual reads yet!)
130 Iterator<MethodDescriptor> methItr = descriptorsToAnalyze.iterator();
131 while (methItr.hasNext()) {
132 Descriptor d = methItr.next();
133 FlatMethod fm = state.getMethodFlat(d);
135 // note we can't use the general liveness analysis already in
136 // the compiler because this analysis is task-aware
137 livenessAnalysisBackward(fm);
140 // 3rd pass, variable analysis
141 methItr = descriptorsToAnalyze.iterator();
142 while (methItr.hasNext()) {
143 Descriptor d = methItr.next();
144 FlatMethod fm = state.getMethodFlat(d);
146 // starting from roots do a forward, fixed-point
147 // variable analysis for refinement and stalls
148 variableAnalysisForward(fm);
151 // 4th pass, compute liveness contribution from
152 // virtual reads discovered in variable pass
153 methItr = descriptorsToAnalyze.iterator();
154 while (methItr.hasNext()) {
155 Descriptor d = methItr.next();
156 FlatMethod fm = state.getMethodFlat(d);
157 livenessAnalysisBackward(fm);
160 // 5th pass, use disjointness with NO FLAGGED REGIONS
161 // to compute taints and effects
162 disjointAnalysisTaints =
163 new DisjointAnalysis(state, typeUtil, callGraph, liveness, arrayReferencees, null,
165 true ); // suppress output--this is an intermediate pass
168 // 6th pass, not available analysis FOR VARIABLES!
169 methItr = descriptorsToAnalyze.iterator();
170 while (methItr.hasNext()) {
171 Descriptor d = methItr.next();
172 FlatMethod fm = state.getMethodFlat(d);
174 // compute what is not available at every program
175 // point, in a forward fixed-point pass
176 notAvailableForward(fm);
179 // 7th pass, make conflict graph
180 // conflict graph is maintained by each parent sese,
182 Set<FlatSESEEnterNode> allSESEs=rblockRel.getAllSESEs();
183 for (Iterator iterator = allSESEs.iterator(); iterator.hasNext();) {
185 FlatSESEEnterNode parent = (FlatSESEEnterNode) iterator.next();
186 if (!parent.getIsLeafSESE()) {
188 EffectsAnalysis effectsAnalysis = disjointAnalysisTaints.getEffectsAnalysis();
189 ConflictGraph conflictGraph = sese2conflictGraph.get(parent);
190 if (conflictGraph == null) {
191 conflictGraph = new ConflictGraph(state);
194 Set<FlatSESEEnterNode> children = parent.getChildren();
195 for (Iterator iterator2 = children.iterator(); iterator2.hasNext();) {
196 FlatSESEEnterNode child = (FlatSESEEnterNode) iterator2.next();
197 Hashtable<Taint, Set<Effect>> taint2Effects = effectsAnalysis.get(child);
198 conflictGraph.addLiveIn(taint2Effects);
199 sese2conflictGraph.put(parent, conflictGraph);
204 Iterator descItr = descriptorsToAnalyze.iterator();
205 while (descItr.hasNext()) {
206 Descriptor d = (Descriptor) descItr.next();
207 FlatMethod fm = state.getMethodFlat(d);
209 makeConflictGraph(fm);
213 // 8th pass, calculate all possible conflicts without using reachability
215 // and identify set of FlatNew that next disjoint reach. analysis should
217 Set<FlatNew> sitesToFlag = new HashSet<FlatNew>();
218 calculateConflicts(sitesToFlag, false);
222 // 9th pass, ask disjoint analysis to compute reachability
223 // for objects that may cause heap conflicts so the most
224 // efficient method to deal with conflict can be computed
226 disjointAnalysisReach =
227 new DisjointAnalysis(state, typeUtil, callGraph, liveness, arrayReferencees, sitesToFlag,
228 null // don't do effects analysis again!
230 // 10th pass, calculate conflicts with reachability info
231 calculateConflicts(null, true);
233 // 11th pass, compiling locks
236 // 12th pass, compute a plan for code injections
237 methItr = descriptorsToAnalyze.iterator();
238 while (methItr.hasNext()) {
239 Descriptor d = methItr.next();
240 FlatMethod fm = state.getMethodFlat(d);
241 codePlansForward(fm);
245 // splice new IR nodes into graph after all
246 // analysis passes are complete
247 Iterator spliceItr = wdvNodesToSpliceIn.entrySet().iterator();
248 while (spliceItr.hasNext()) {
249 Map.Entry me = (Map.Entry) spliceItr.next();
250 FlatWriteDynamicVarNode fwdvn = (FlatWriteDynamicVarNode) me.getValue();
251 fwdvn.spliceIntoIR();
255 if (state.OOODEBUG) {
258 //disjointAnalysisTaints.getEffectsAnalysis().writeEffects("effects.txt");
259 //writeConflictGraph();
260 } catch (IOException e) {}
263 System.out.println("\n\n\n##########################################################\n"+
264 "Warning, lots of code changes going on, OoOJava and RCR/DFJ\n"+
265 "systems are being cleaned up. Until the analyses and code gen\n"+
266 "are fully altered and coordinated, these systems will not run\n"+
267 "to completion. Partial stable check-ins are necessary to manage\n"+
268 "the number of files getting touched.\n"+
269 "##########################################################" );
277 * Iterator iter = sese2conflictGraph.entrySet().iterator(); while
278 * (iter.hasNext()) { Entry e = (Entry) iter.next(); FlatNode fn =
279 * (FlatNode) e.getKey(); ConflictGraph conflictGraph = (ConflictGraph)
281 * System.out.println("---------------------------------------");
282 * System.out.println("CONFLICT GRAPH for " + fn); Set<String> keySet =
283 * conflictGraph.id2cn.keySet(); for (Iterator iterator = keySet.iterator();
284 * iterator.hasNext();) { String key = (String) iterator.next();
285 * ConflictNode node = conflictGraph.id2cn.get(key);
286 * System.out.println("key=" + key + " \n" + node.toStringAllEffects()); } }
292 private void writeFile(Set<FlatNew> sitesToFlag) {
295 BufferedWriter bw = new BufferedWriter(new FileWriter("sitesToFlag.txt"));
297 for (Iterator iterator = sitesToFlag.iterator(); iterator.hasNext();) {
298 FlatNew fn = (FlatNew) iterator.next();
302 } catch (IOException e) {
309 private void livenessAnalysisBackward(FlatMethod fm) {
311 // flow backward across nodes to compute liveness, and
312 // take special care with sese enter/exit nodes that
313 // alter this from normal liveness analysis
314 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
315 flatNodesToVisit.add( fm.getFlatExit() );
317 while( !flatNodesToVisit.isEmpty() ) {
318 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
319 flatNodesToVisit.remove( fn );
321 Set<TempDescriptor> prev = livenessGlobalView.get( fn );
323 // merge sets from control flow joins
324 Set<TempDescriptor> livein = new HashSet<TempDescriptor>();
325 for (int i = 0; i < fn.numNext(); i++) {
326 FlatNode nn = fn.getNext( i );
327 Set<TempDescriptor> s = livenessGlobalView.get( nn );
333 Set<TempDescriptor> curr = liveness_nodeActions( fn, livein );
335 // if a new result, schedule backward nodes for analysis
336 if( !curr.equals( prev ) ) {
337 livenessGlobalView.put( fn, curr );
339 for( int i = 0; i < fn.numPrev(); i++ ) {
340 FlatNode nn = fn.getPrev( i );
341 flatNodesToVisit.add( nn );
347 private Set<TempDescriptor> liveness_nodeActions( FlatNode fn,
348 Set<TempDescriptor> liveIn
350 switch( fn.kind() ) {
352 case FKind.FlatSESEEnterNode: {
353 // add whatever is live-in at a task enter to that
355 FlatSESEEnterNode fsen = (FlatSESEEnterNode)fn;
356 if( liveIn != null ) {
357 fsen.addInVarSet( liveIn );
359 // no break, should also execute default actions
363 // handle effects of statement in reverse, writes then reads
364 TempDescriptor[] writeTemps = fn.writesTemps();
365 for( int i = 0; i < writeTemps.length; ++i ) {
366 liveIn.remove( writeTemps[i] );
368 // if we are analyzing code declared directly in a task,
369 FlatSESEEnterNode fsen = rblockRel.getLocalInnerRBlock( fn );
371 // check to see if we are writing to variables that will
372 // be live-out at the task's exit (and therefore should
373 // go in the task's out-var set)
374 FlatSESEExitNode fsexn = fsen.getFlatExit();
375 Set<TempDescriptor> livetemps = livenessGlobalView.get( fsexn );
376 if( livetemps != null && livetemps.contains( writeTemps[i] ) ) {
377 fsen.addOutVar( writeTemps[i] );
382 TempDescriptor[] readTemps = fn.readsTemps();
383 for( int i = 0; i < readTemps.length; ++i ) {
384 liveIn.add( readTemps[i] );
387 Set<TempDescriptor> virtualReadTemps = livenessVirtualReads.get( fn );
388 if( virtualReadTemps != null ) {
389 liveIn.addAll( virtualReadTemps );
399 private void variableAnalysisForward(FlatMethod fm) {
401 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
402 flatNodesToVisit.add(fm);
404 while (!flatNodesToVisit.isEmpty()) {
405 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
406 flatNodesToVisit.remove(fn);
408 VarSrcTokTable prev = variableResults.get(fn);
410 // merge sets from control flow joins
411 VarSrcTokTable curr = new VarSrcTokTable();
412 for (int i = 0; i < fn.numPrev(); i++) {
413 FlatNode nn = fn.getPrev(i);
414 VarSrcTokTable incoming = variableResults.get(nn);
415 curr.merge(incoming);
418 FlatSESEEnterNode currentSESE = rblockRel.getLocalInnerRBlock( fn );
419 if( currentSESE == null ) {
420 currentSESE = rblockRel.getCallerProxySESE();
423 variable_nodeActions(fn, curr, currentSESE);
425 // if a new result, schedule forward nodes for analysis
426 if (!curr.equals(prev)) {
427 variableResults.put(fn, curr);
429 for (int i = 0; i < fn.numNext(); i++) {
430 FlatNode nn = fn.getNext(i);
431 flatNodesToVisit.add(nn);
437 private void variable_nodeActions(FlatNode fn,
438 VarSrcTokTable vstTable,
439 FlatSESEEnterNode currentSESE) {
443 case FKind.FlatSESEEnterNode: {
444 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
445 // ignore currently executing SESE, at this point
446 // the analysis considers a new instance is becoming
449 vstTable.assertConsistency();
453 case FKind.FlatSESEExitNode: {
454 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
456 // fsen is the child of currently executing tasks
457 FlatSESEEnterNode fsen = fsexn.getFlatEnter();
459 // remap all of this child's children tokens to be
460 // from this child as the child exits
461 vstTable.remapChildTokens(fsen);
463 // liveness virtual reads are things that might be
464 // written by an SESE and should be added to the in-set
465 // anything virtually read by this SESE should be pruned
466 // of parent or sibling sources
467 Set<TempDescriptor> liveVars = livenessGlobalView.get(fn);
468 Set<TempDescriptor> fsenVirtReads =
469 vstTable.calcVirtReadsAndPruneParentAndSiblingTokens(fsen,
472 Set<TempDescriptor> fsenVirtReadsOld = livenessVirtualReads.get(fn);
473 if (fsenVirtReadsOld != null) {
474 fsenVirtReads.addAll(fsenVirtReadsOld);
476 livenessVirtualReads.put(fn, fsenVirtReads);
478 // then all child out-set tokens are guaranteed
479 // to be filled in, so clobber those entries with
480 // the latest, clean sources
481 Iterator<TempDescriptor> outVarItr = fsen.getOutVarSet().iterator();
482 while (outVarItr.hasNext()) {
483 TempDescriptor outVar = outVarItr.next();
484 HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
486 VariableSourceToken vst = new VariableSourceToken(ts, fsen, new Integer(0), outVar);
487 vstTable.remove(outVar);
490 vstTable.assertConsistency();
494 case FKind.FlatOpNode: {
495 FlatOpNode fon = (FlatOpNode) fn;
497 if (fon.getOp().getOp() == Operation.ASSIGN) {
498 TempDescriptor lhs = fon.getDest();
499 TempDescriptor rhs = fon.getLeft();
501 vstTable.remove(lhs);
503 Set<VariableSourceToken> forAddition = new HashSet<VariableSourceToken>();
505 Iterator<VariableSourceToken> itr = vstTable.get(rhs).iterator();
506 while (itr.hasNext()) {
507 VariableSourceToken vst = itr.next();
509 HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
512 // when we do x = y for variables, just copy over from a child,
513 // there are two cases:
514 // 1. if the current task is the caller proxy, any local root is a child
516 currentSESE.getIsCallerProxySESE() &&
517 rblockRel.getLocalRootSESEs().contains( vst.getSESE() );
519 // 2. if the child task is a locally-defined child of the current task
520 boolean case2 = currentSESE.getLocalChildren().contains( vst.getSESE() );
522 if( case1 || case2 ) {
523 // if the source comes from a child, copy it over
524 forAddition.add( new VariableSourceToken( ts,
531 // otherwise, stamp it as us as the source
532 forAddition.add( new VariableSourceToken( ts,
541 vstTable.addAll( forAddition );
543 // only break if this is an ASSIGN op node,
544 // otherwise fall through to default case
545 vstTable.assertConsistency();
550 // note that FlatOpNode's that aren't ASSIGN
551 // fall through to this default case
553 TempDescriptor[] writeTemps = fn.writesTemps();
554 if( writeTemps.length > 0 ) {
556 // for now, when writeTemps > 1, make sure
557 // its a call node, programmer enforce only
558 // doing stuff like calling a print routine
559 if( writeTemps.length > 1 ) {
560 assert fn.kind() == FKind.FlatCall || fn.kind() == FKind.FlatMethod;
564 vstTable.remove( writeTemps[0] );
566 HashSet<TempDescriptor> ts = new HashSet<TempDescriptor>();
567 ts.add( writeTemps[0] );
569 vstTable.add( new VariableSourceToken( ts,
577 vstTable.assertConsistency();
584 private void notAvailableForward(FlatMethod fm) {
586 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
587 flatNodesToVisit.add(fm);
589 while (!flatNodesToVisit.isEmpty()) {
590 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
591 flatNodesToVisit.remove(fn);
593 Stack<FlatSESEEnterNode> seseStack = null; //rblockRel.getRBlockStacks(fm, fn);
594 assert seseStack != null;
596 Set<TempDescriptor> prev = notAvailableResults.get(fn);
598 Set<TempDescriptor> curr = new HashSet<TempDescriptor>();
599 for (int i = 0; i < fn.numPrev(); i++) {
600 FlatNode nn = fn.getPrev(i);
601 Set<TempDescriptor> notAvailIn = notAvailableResults.get(nn);
602 if (notAvailIn != null) {
603 curr.addAll(notAvailIn);
607 if (!seseStack.empty()) {
608 notAvailable_nodeActions(fn, curr, seseStack.peek());
611 // if a new result, schedule forward nodes for analysis
612 if (!curr.equals(prev)) {
613 notAvailableResults.put(fn, curr);
615 for (int i = 0; i < fn.numNext(); i++) {
616 FlatNode nn = fn.getNext(i);
617 flatNodesToVisit.add(nn);
623 private void notAvailable_nodeActions(FlatNode fn, Set<TempDescriptor> notAvailSet,
624 FlatSESEEnterNode currentSESE) {
626 // any temps that are removed from the not available set
627 // at this node should be marked in this node's code plan
628 // as temps to be grabbed at runtime!
632 case FKind.FlatSESEEnterNode: {
633 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
634 assert fsen.equals(currentSESE);
636 // keep a copy of what's not available into the SESE
637 // and restore it at the matching exit node
638 Set<TempDescriptor> notAvailCopy = new HashSet<TempDescriptor>();
639 Iterator<TempDescriptor> tdItr = notAvailSet.iterator();
640 while (tdItr.hasNext()) {
641 notAvailCopy.add(tdItr.next());
643 notAvailableIntoSESE.put(fsen, notAvailCopy);
649 case FKind.FlatSESEExitNode: {
650 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
651 FlatSESEEnterNode fsen = fsexn.getFlatEnter();
652 assert currentSESE.getChildren().contains(fsen);
654 notAvailSet.addAll(fsen.getOutVarSet());
656 Set<TempDescriptor> notAvailIn = notAvailableIntoSESE.get(fsen);
657 assert notAvailIn != null;
658 notAvailSet.addAll(notAvailIn);
663 case FKind.FlatMethod: {
667 case FKind.FlatOpNode: {
668 FlatOpNode fon = (FlatOpNode) fn;
670 if (fon.getOp().getOp() == Operation.ASSIGN) {
671 TempDescriptor lhs = fon.getDest();
672 TempDescriptor rhs = fon.getLeft();
674 // copy makes lhs same availability as rhs
675 if (notAvailSet.contains(rhs)) {
676 notAvailSet.add(lhs);
678 notAvailSet.remove(lhs);
681 // only break if this is an ASSIGN op node,
682 // otherwise fall through to default case
687 // note that FlatOpNode's that aren't ASSIGN
688 // fall through to this default case
690 TempDescriptor[] writeTemps = fn.writesTemps();
691 for (int i = 0; i < writeTemps.length; i++) {
692 TempDescriptor wTemp = writeTemps[i];
693 notAvailSet.remove(wTemp);
695 TempDescriptor[] readTemps = fn.readsTemps();
696 for (int i = 0; i < readTemps.length; i++) {
697 TempDescriptor rTemp = readTemps[i];
698 notAvailSet.remove(rTemp);
700 // if this variable has exactly one source, potentially
701 // get other things from this source as well
702 VarSrcTokTable vstTable = variableResults.get(fn);
704 VSTWrapper vstIfStatic = new VSTWrapper();
705 Integer srcType = vstTable.getRefVarSrcType(rTemp, currentSESE, vstIfStatic);
707 if (srcType.equals(VarSrcTokTable.SrcType_STATIC)) {
709 VariableSourceToken vst = vstIfStatic.vst;
711 Iterator<VariableSourceToken> availItr =
712 vstTable.get(vst.getSESE(), vst.getAge()).iterator();
714 // look through things that are also available from same source
715 while (availItr.hasNext()) {
716 VariableSourceToken vstAlsoAvail = availItr.next();
718 Iterator<TempDescriptor> refVarItr = vstAlsoAvail.getRefVars().iterator();
719 while (refVarItr.hasNext()) {
720 TempDescriptor refVarAlso = refVarItr.next();
722 // if a variable is available from the same source, AND it ALSO
723 // only comes from one statically known source, mark it available
724 VSTWrapper vstIfStaticNotUsed = new VSTWrapper();
725 Integer srcTypeAlso =
726 vstTable.getRefVarSrcType(refVarAlso, currentSESE, vstIfStaticNotUsed);
727 if (srcTypeAlso.equals(VarSrcTokTable.SrcType_STATIC)) {
728 notAvailSet.remove(refVarAlso);
740 private void codePlansForward(FlatMethod fm) {
742 // start from flat method top, visit every node in
743 // method exactly once
744 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
745 flatNodesToVisit.add(fm);
747 Set<FlatNode> visited = new HashSet<FlatNode>();
749 while (!flatNodesToVisit.isEmpty()) {
750 Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
751 FlatNode fn = fnItr.next();
753 flatNodesToVisit.remove(fn);
756 Stack<FlatSESEEnterNode> seseStack = null; //rblockRel.getRBlockStacks(fm, fn);
757 assert seseStack != null;
759 // use incoming results as "dot statement" or just
760 // before the current statement
761 VarSrcTokTable dotSTtable = new VarSrcTokTable();
762 for (int i = 0; i < fn.numPrev(); i++) {
763 FlatNode nn = fn.getPrev(i);
764 dotSTtable.merge(variableResults.get(nn));
767 // find dt-st notAvailableSet also
768 Set<TempDescriptor> dotSTnotAvailSet = new HashSet<TempDescriptor>();
769 for (int i = 0; i < fn.numPrev(); i++) {
770 FlatNode nn = fn.getPrev(i);
771 Set<TempDescriptor> notAvailIn = notAvailableResults.get(nn);
772 if (notAvailIn != null) {
773 dotSTnotAvailSet.addAll(notAvailIn);
777 Set<TempDescriptor> dotSTlive = livenessGlobalView.get(fn);
779 if (!seseStack.empty()) {
780 codePlans_nodeActions(fn, dotSTlive, dotSTtable, dotSTnotAvailSet, seseStack.peek());
783 for (int i = 0; i < fn.numNext(); i++) {
784 FlatNode nn = fn.getNext(i);
786 if (!visited.contains(nn)) {
787 flatNodesToVisit.add(nn);
793 private void codePlans_nodeActions(FlatNode fn, Set<TempDescriptor> liveSetIn,
794 VarSrcTokTable vstTableIn, Set<TempDescriptor> notAvailSetIn, FlatSESEEnterNode currentSESE) {
796 CodePlan plan = new CodePlan(currentSESE);
800 case FKind.FlatSESEEnterNode: {
801 FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
802 assert fsen.equals(currentSESE);
804 // track the source types of the in-var set so generated
805 // code at this SESE issue can compute the number of
806 // dependencies properly
807 Iterator<TempDescriptor> inVarItr = fsen.getInVarSet().iterator();
808 while (inVarItr.hasNext()) {
809 TempDescriptor inVar = inVarItr.next();
811 // when we get to an SESE enter node we change the
812 // currentSESE variable of this analysis to the
813 // child that is declared by the enter node, so
814 // in order to classify in-vars correctly, pass
815 // the parent SESE in--at other FlatNode types just
816 // use the currentSESE
817 VSTWrapper vstIfStatic = new VSTWrapper();
818 Integer srcType = null; //vstTableIn.getRefVarSrcType(inVar, fsen.getParent(), vstIfStatic);
820 // the current SESE needs a local space to track the dynamic
821 // variable and the child needs space in its SESE record
822 if (srcType.equals(VarSrcTokTable.SrcType_DYNAMIC)) {
823 fsen.addDynamicInVar(inVar);
824 // %@%@%@%@%@%@%@% TODO!!!! @%@%@%@%@% fsen.getParent().addDynamicVar(inVar);
826 } else if (srcType.equals(VarSrcTokTable.SrcType_STATIC)) {
827 fsen.addStaticInVar(inVar);
828 VariableSourceToken vst = vstIfStatic.vst;
829 fsen.putStaticInVar2src(inVar, vst);
830 fsen.addStaticInVarSrc(new SESEandAgePair(vst.getSESE(), vst.getAge()));
832 assert srcType.equals(VarSrcTokTable.SrcType_READY);
833 fsen.addReadyInVar(inVar);
840 case FKind.FlatSESEExitNode: {
841 FlatSESEExitNode fsexn = (FlatSESEExitNode) fn;
845 case FKind.FlatOpNode: {
846 FlatOpNode fon = (FlatOpNode) fn;
848 if (fon.getOp().getOp() == Operation.ASSIGN) {
849 TempDescriptor lhs = fon.getDest();
850 TempDescriptor rhs = fon.getLeft();
852 // if this is an op node, don't stall, copy
853 // source and delay until we need to use value
855 // ask whether lhs and rhs sources are dynamic, static, etc.
856 VSTWrapper vstIfStatic = new VSTWrapper();
857 Integer lhsSrcType = vstTableIn.getRefVarSrcType(lhs, currentSESE, vstIfStatic);
858 Integer rhsSrcType = vstTableIn.getRefVarSrcType(rhs, currentSESE, vstIfStatic);
860 if (rhsSrcType.equals(VarSrcTokTable.SrcType_DYNAMIC)) {
861 // if rhs is dynamic going in, lhs will definitely be dynamic
862 // going out of this node, so track that here
863 plan.addDynAssign(lhs, rhs);
864 currentSESE.addDynamicVar(lhs);
865 currentSESE.addDynamicVar(rhs);
867 } else if (lhsSrcType.equals(VarSrcTokTable.SrcType_DYNAMIC)) {
868 // otherwise, if the lhs is dynamic, but the rhs is not, we
869 // need to update the variable's dynamic source as "current SESE"
870 plan.addDynAssign(lhs);
873 // only break if this is an ASSIGN op node,
874 // otherwise fall through to default case
879 // note that FlatOpNode's that aren't ASSIGN
880 // fall through to this default case
883 // a node with no live set has nothing to stall for
884 if (liveSetIn == null) {
888 TempDescriptor[] readarray = fn.readsTemps();
889 for (int i = 0; i < readarray.length; i++) {
890 TempDescriptor readtmp = readarray[i];
892 // ignore temps that are definitely available
893 // when considering to stall on it
894 if (!notAvailSetIn.contains(readtmp)) {
898 // check the source type of this variable
899 VSTWrapper vstIfStatic = new VSTWrapper();
900 Integer srcType = vstTableIn.getRefVarSrcType(readtmp, currentSESE, vstIfStatic);
902 if (srcType.equals(VarSrcTokTable.SrcType_DYNAMIC)) {
903 // 1) It is not clear statically where this variable will
904 // come from, so dynamically we must keep track
905 // along various control paths, and therefore when we stall,
906 // just stall for the exact thing we need and move on
907 plan.addDynamicStall(readtmp);
908 currentSESE.addDynamicVar(readtmp);
910 } else if (srcType.equals(VarSrcTokTable.SrcType_STATIC)) {
911 // 2) Single token/age pair: Stall for token/age pair, and copy
912 // all live variables with same token/age pair at the same
913 // time. This is the same stuff that the notavaialable analysis
914 // marks as now available.
915 VariableSourceToken vst = vstIfStatic.vst;
917 Iterator<VariableSourceToken> availItr =
918 vstTableIn.get(vst.getSESE(), vst.getAge()).iterator();
920 while (availItr.hasNext()) {
921 VariableSourceToken vstAlsoAvail = availItr.next();
923 // only grab additional stuff that is live
924 Set<TempDescriptor> copySet = new HashSet<TempDescriptor>();
926 Iterator<TempDescriptor> refVarItr = vstAlsoAvail.getRefVars().iterator();
927 while (refVarItr.hasNext()) {
928 TempDescriptor refVar = refVarItr.next();
929 if (liveSetIn.contains(refVar)) {
934 if (!copySet.isEmpty()) {
935 plan.addStall2CopySet(vstAlsoAvail, copySet);
940 // the other case for srcs is READY, so do nothing
943 // assert that everything being stalled for is in the
944 // "not available" set coming into this flat node and
945 // that every VST identified is in the possible "stall set"
946 // that represents VST's from children SESE's
954 // identify sese-age pairs that are statically useful
955 // and should have an associated SESE variable in code
956 // JUST GET ALL SESE/AGE NAMES FOR NOW, PRUNE LATER,
957 // AND ALWAYS GIVE NAMES TO PARENTS
958 Set<VariableSourceToken> staticSet = vstTableIn.get();
959 Iterator<VariableSourceToken> vstItr = staticSet.iterator();
960 while (vstItr.hasNext()) {
961 VariableSourceToken vst = vstItr.next();
963 // placeholder source tokens are useful results, but
964 // the placeholder static name is never needed
965 //if (vst.getSESE().getIsCallerSESEplaceholder()) {
969 FlatSESEEnterNode sese = currentSESE;
970 while (sese != null) {
971 sese.addNeededStaticName(new SESEandAgePair(vst.getSESE(), vst.getAge()));
972 sese.mustTrackAtLeastAge(vst.getAge());
974 //@%@%@%@%@%@% TODO!!!!! @%@%@%@%@%@% sese = sese.getParent();
978 codePlans.put(fn, plan);
980 // if any variables at this-node-*dot* have a static source (exactly one
982 // but go to a dynamic source at next-node-*dot*, create a new IR graph
983 // node on that edge to track the sources dynamically
984 VarSrcTokTable thisVstTable = variableResults.get(fn);
985 for (int i = 0; i < fn.numNext(); i++) {
986 FlatNode nn = fn.getNext(i);
987 VarSrcTokTable nextVstTable = variableResults.get(nn);
988 Set<TempDescriptor> nextLiveIn = livenessGlobalView.get(nn);
990 // the table can be null if it is one of the few IR nodes
991 // completely outside of the root SESE scope
992 if (nextVstTable != null && nextLiveIn != null) {
994 Hashtable<TempDescriptor, VSTWrapper> readyOrStatic2dynamicSet =
995 thisVstTable.getReadyOrStatic2DynamicSet(nextVstTable, nextLiveIn, currentSESE);
997 if (!readyOrStatic2dynamicSet.isEmpty()) {
999 // either add these results to partial fixed-point result
1000 // or make a new one if we haven't made any here yet
1001 FlatEdge fe = new FlatEdge(fn, nn);
1002 FlatWriteDynamicVarNode fwdvn = wdvNodesToSpliceIn.get(fe);
1004 if (fwdvn == null) {
1005 fwdvn = new FlatWriteDynamicVarNode(fn, nn, readyOrStatic2dynamicSet, currentSESE);
1006 wdvNodesToSpliceIn.put(fe, fwdvn);
1008 fwdvn.addMoreVar2Src(readyOrStatic2dynamicSet);
1015 private void makeConflictGraph(FlatMethod fm) {
1017 System.out.println( "Creating conflict graph for "+fm );
1019 Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
1020 flatNodesToVisit.add(fm);
1022 Set<FlatNode> visited = new HashSet<FlatNode>();
1024 while (!flatNodesToVisit.isEmpty()) {
1025 FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
1026 flatNodesToVisit.remove(fn);
1029 Stack<FlatSESEEnterNode> seseStack = null; //rblockRel.getRBlockStacks(fm, fn);
1030 assert seseStack != null;
1032 if (!seseStack.isEmpty()) {
1033 conflictGraph_nodeAction(fn, seseStack.peek());
1036 // schedule forward nodes for analysis
1037 for (int i = 0; i < fn.numNext(); i++) {
1038 FlatNode nn = fn.getNext(i);
1039 if (!visited.contains(nn)) {
1040 flatNodesToVisit.add(nn);
1048 private void conflictGraph_nodeAction(FlatNode fn, FlatSESEEnterNode currentSESE) {
1050 ConflictGraph conflictGraph;
1054 EffectsAnalysis effectsAnalysis = disjointAnalysisTaints.getEffectsAnalysis();
1057 switch (fn.kind()) {
1060 case FKind.FlatFieldNode:
1061 case FKind.FlatElementNode: {
1063 if (fn instanceof FlatFieldNode) {
1064 FlatFieldNode ffn = (FlatFieldNode) fn;
1067 FlatElementNode fen = (FlatElementNode) fn;
1071 conflictGraph = sese2conflictGraph.get(currentSESE);
1072 if (conflictGraph == null) {
1073 conflictGraph = new ConflictGraph(state);
1077 Hashtable<Taint, Set<Effect>> taint2Effects = effectsAnalysis.get(fn);
1078 conflictGraph.addStallSite(taint2Effects, rhs);
1080 if (conflictGraph.id2cn.size() > 0) {
1081 sese2conflictGraph.put(currentSESE, conflictGraph);
1086 case FKind.FlatSetFieldNode:
1087 case FKind.FlatSetElementNode: {
1089 if (fn instanceof FlatSetFieldNode) {
1090 FlatSetFieldNode fsfn = (FlatSetFieldNode) fn;
1091 lhs = fsfn.getDst();
1092 rhs = fsfn.getSrc();
1094 FlatSetElementNode fsen = (FlatSetElementNode) fn;
1095 lhs = fsen.getDst();
1096 rhs = fsen.getSrc();
1099 conflictGraph = sese2conflictGraph.get(currentSESE);
1100 if (conflictGraph == null) {
1101 conflictGraph = new ConflictGraph(state);
1104 Hashtable<Taint, Set<Effect>> taint2Effects = effectsAnalysis.get(fn);
1105 conflictGraph.addStallSite(taint2Effects, rhs);
1106 conflictGraph.addStallSite(taint2Effects, lhs);
1108 if (conflictGraph.id2cn.size() > 0) {
1109 sese2conflictGraph.put(currentSESE, conflictGraph);
1113 case FKind.FlatCall: {
1114 conflictGraph = sese2conflictGraph.get(currentSESE);
1115 if (conflictGraph == null) {
1116 conflictGraph = new ConflictGraph(state);
1119 FlatCall fc = (FlatCall) fn;
1122 // collects effects of stall site and generates stall site node
1123 Hashtable<Taint, Set<Effect>> taint2Effects = effectsAnalysis.get(fn);
1125 conflictGraph.addStallSite(taint2Effects, lhs);
1126 if (conflictGraph.id2cn.size() > 0) {
1127 sese2conflictGraph.put(currentSESE, conflictGraph);
1136 private void calculateConflicts(Set<FlatNew> sitesToFlag, boolean useReachInfo) {
1137 // decide fine-grain edge or coarse-grain edge among all vertexes by
1138 // pair-wise comparison
1139 Iterator<FlatNode> seseIter = sese2conflictGraph.keySet().iterator();
1140 while (seseIter.hasNext()) {
1141 FlatSESEEnterNode sese = (FlatSESEEnterNode) seseIter.next();
1142 ConflictGraph conflictGraph = sese2conflictGraph.get(sese);
1143 // System.out.println("# CALCULATING SESE CONFLICT="+sese);
1145 // clear current conflict before recalculating with reachability info
1146 conflictGraph.clearAllConflictEdge();
1147 conflictGraph.setDisJointAnalysis(disjointAnalysisReach);
1148 conflictGraph.setFMEnclosing(sese.getfmEnclosing());
1150 conflictGraph.analyzeConflicts(sitesToFlag, useReachInfo);
1151 sese2conflictGraph.put(sese, conflictGraph);
1155 private void writeConflictGraph() {
1156 Enumeration<FlatNode> keyEnum = sese2conflictGraph.keys();
1157 while (keyEnum.hasMoreElements()) {
1158 FlatNode key = (FlatNode) keyEnum.nextElement();
1159 ConflictGraph cg = sese2conflictGraph.get(key);
1161 if (cg.hasConflictEdge()) {
1162 cg.writeGraph("ConflictGraphFor" + key, false);
1164 } catch (IOException e) {
1165 System.out.println("Error writing");
1171 private void synthesizeLocks() {
1172 Set<Entry<FlatNode, ConflictGraph>> graphEntrySet = sese2conflictGraph.entrySet();
1173 for (Iterator iterator = graphEntrySet.iterator(); iterator.hasNext();) {
1174 Entry<FlatNode, ConflictGraph> graphEntry = (Entry<FlatNode, ConflictGraph>) iterator.next();
1175 FlatNode sese = graphEntry.getKey();
1176 ConflictGraph conflictGraph = graphEntry.getValue();
1177 calculateCovering(conflictGraph);
1181 private void calculateCovering(ConflictGraph conflictGraph) {
1182 uniqueLockSetId = 0; // reset lock counter for every new conflict graph
1183 HashSet<ConflictEdge> fineToCover = new HashSet<ConflictEdge>();
1184 HashSet<ConflictEdge> coarseToCover = new HashSet<ConflictEdge>();
1185 HashSet<SESELock> lockSet = new HashSet<SESELock>();
1187 Set<ConflictEdge> tempCover = conflictGraph.getEdgeSet();
1188 for (Iterator iterator = tempCover.iterator(); iterator.hasNext();) {
1189 ConflictEdge conflictEdge = (ConflictEdge) iterator.next();
1190 if (conflictEdge.isCoarseEdge()) {
1191 coarseToCover.add(conflictEdge);
1193 fineToCover.add(conflictEdge);
1197 HashSet<ConflictEdge> toCover = new HashSet<ConflictEdge>();
1198 toCover.addAll(fineToCover);
1199 toCover.addAll(coarseToCover);
1201 while (!toCover.isEmpty()) {
1203 SESELock seseLock = new SESELock();
1204 seseLock.setID(uniqueLockSetId++);
1208 do { // fine-grained edge
1212 for (Iterator iterator = fineToCover.iterator(); iterator.hasNext();) {
1215 ConflictEdge edge = (ConflictEdge) iterator.next();
1216 if (seseLock.getConflictNodeSet().size() == 0) {
1218 if (seseLock.isWriteNode(edge.getVertexU())) {
1219 // mark as fine_write
1220 if (edge.getVertexU().isStallSiteNode()) {
1221 type = ConflictNode.PARENT_WRITE;
1223 type = ConflictNode.FINE_WRITE;
1225 seseLock.addConflictNode(edge.getVertexU(), type);
1227 // mark as fine_read
1228 if (edge.getVertexU().isStallSiteNode()) {
1229 type = ConflictNode.PARENT_READ;
1231 type = ConflictNode.FINE_READ;
1233 seseLock.addConflictNode(edge.getVertexU(), type);
1235 if (edge.getVertexV() != edge.getVertexU()) {
1236 if (seseLock.isWriteNode(edge.getVertexV())) {
1237 // mark as fine_write
1238 if (edge.getVertexV().isStallSiteNode()) {
1239 type = ConflictNode.PARENT_WRITE;
1241 type = ConflictNode.FINE_WRITE;
1243 seseLock.addConflictNode(edge.getVertexV(), type);
1245 // mark as fine_read
1246 if (edge.getVertexV().isStallSiteNode()) {
1247 type = ConflictNode.PARENT_READ;
1249 type = ConflictNode.FINE_READ;
1251 seseLock.addConflictNode(edge.getVertexV(), type);
1255 seseLock.addConflictEdge(edge);
1256 fineToCover.remove(edge);
1257 break;// exit iterator loop
1258 }// end of initial setup
1260 ConflictNode newNode;
1261 if ((newNode = seseLock.getNewNodeConnectedWithGroup(edge)) != null) {
1262 // new node has a fine-grained edge to all current node
1263 // If there is a coarse grained edge where need a fine edge, it's
1264 // okay to add the node
1265 // but the edge must remain uncovered.
1269 if (seseLock.containsConflictNode(newNode)) {
1270 seseLock.addEdge(edge);
1271 fineToCover.remove(edge);
1275 if (seseLock.isWriteNode(newNode)) {
1276 if (newNode.isStallSiteNode()) {
1277 type = ConflictNode.PARENT_WRITE;
1279 type = ConflictNode.FINE_WRITE;
1281 seseLock.setNodeType(newNode, type);
1283 if (newNode.isStallSiteNode()) {
1284 type = ConflictNode.PARENT_READ;
1286 type = ConflictNode.FINE_READ;
1288 seseLock.setNodeType(newNode, type);
1291 seseLock.addEdge(edge);
1292 Set<ConflictEdge> edgeSet = newNode.getEdgeSet();
1293 for (Iterator iterator2 = edgeSet.iterator(); iterator2.hasNext();) {
1294 ConflictEdge conflictEdge = (ConflictEdge) iterator2.next();
1296 // mark all fine edges between new node and nodes in the group as
1298 if (!conflictEdge.getVertexU().equals(newNode)) {
1299 if (seseLock.containsConflictNode(conflictEdge.getVertexU())) {
1301 seseLock.addConflictEdge(conflictEdge);
1302 fineToCover.remove(conflictEdge);
1304 } else if (!conflictEdge.getVertexV().equals(newNode)) {
1305 if (seseLock.containsConflictNode(conflictEdge.getVertexV())) {
1307 seseLock.addConflictEdge(conflictEdge);
1308 fineToCover.remove(conflictEdge);
1314 break;// exit iterator loop
1319 HashSet<ConflictEdge> notCovered=new HashSet<ConflictEdge>();
1323 for (Iterator iterator = coarseToCover.iterator(); iterator.hasNext();) {
1325 ConflictEdge edge = (ConflictEdge) iterator.next();
1326 if (seseLock.getConflictNodeSet().size() == 0) {
1328 if (seseLock.hasSelfCoarseEdge(edge.getVertexU())) {
1329 // node has a coarse-grained edge with itself
1330 if (!(edge.getVertexU().isStallSiteNode())) {
1331 // and it is not parent
1332 type = ConflictNode.SCC;
1335 type = ConflictNode.PARENT_COARSE;
1337 type = ConflictNode.PARENT_WRITE;
1340 seseLock.addConflictNode(edge.getVertexU(), type);
1342 if (edge.getVertexU().isStallSiteNode()) {
1344 type = ConflictNode.PARENT_COARSE;
1346 if (edge.getVertexU().getWriteEffectSet().isEmpty()) {
1347 type = ConflictNode.PARENT_READ;
1349 type = ConflictNode.PARENT_WRITE;
1353 type = ConflictNode.COARSE;
1355 seseLock.addConflictNode(edge.getVertexU(), type);
1357 if (seseLock.hasSelfCoarseEdge(edge.getVertexV())) {
1358 // node has a coarse-grained edge with itself
1359 if (!(edge.getVertexV().isStallSiteNode())) {
1360 // and it is not parent
1361 type = ConflictNode.SCC;
1364 type = ConflictNode.PARENT_COARSE;
1366 type = ConflictNode.PARENT_WRITE;
1369 seseLock.addConflictNode(edge.getVertexV(), type);
1371 if (edge.getVertexV().isStallSiteNode()) {
1373 type = ConflictNode.PARENT_COARSE;
1375 if (edge.getVertexV().getWriteEffectSet().isEmpty()) {
1376 type = ConflictNode.PARENT_READ;
1378 type = ConflictNode.PARENT_WRITE;
1382 type = ConflictNode.COARSE;
1384 seseLock.addConflictNode(edge.getVertexV(), type);
1387 coarseToCover.remove(edge);
1388 seseLock.addConflictEdge(edge);
1389 break;// exit iterator loop
1390 }// end of initial setup
1392 ConflictNode newNode;
1393 if ((newNode = seseLock.getNewNodeConnectedWithGroup(edge)) != null) {
1394 // new node has a coarse-grained edge to all fine-read, fine-write,
1398 if (newNode.isInVarNode() && (!seseLock.hasSelfCoarseEdge(newNode))
1399 && seseLock.hasCoarseEdgeWithParentCoarse(newNode)) {
1400 // this case can't be covered by this queue
1401 coarseToCover.remove(edge);
1402 notCovered.add(edge);
1406 if (seseLock.containsConflictNode(newNode)) {
1407 seseLock.addEdge(edge);
1408 coarseToCover.remove(edge);
1412 if (seseLock.hasSelfCoarseEdge(newNode)) {
1414 if (newNode.isStallSiteNode()) {
1415 type = ConflictNode.PARENT_COARSE;
1417 type = ConflictNode.SCC;
1419 seseLock.setNodeType(newNode, type);
1421 if (newNode.isStallSiteNode()) {
1422 type = ConflictNode.PARENT_COARSE;
1424 type = ConflictNode.COARSE;
1426 seseLock.setNodeType(newNode, type);
1429 seseLock.addEdge(edge);
1430 Set<ConflictEdge> edgeSet = newNode.getEdgeSet();
1431 for (Iterator iterator2 = edgeSet.iterator(); iterator2.hasNext();) {
1432 ConflictEdge conflictEdge = (ConflictEdge) iterator2.next();
1433 // mark all coarse edges between new node and nodes in the group
1435 if (!conflictEdge.getVertexU().equals(newNode)) {
1436 if (seseLock.containsConflictNode(conflictEdge.getVertexU())) {
1438 seseLock.addConflictEdge(conflictEdge);
1439 coarseToCover.remove(conflictEdge);
1441 } else if (!conflictEdge.getVertexV().equals(newNode)) {
1442 if (seseLock.containsConflictNode(conflictEdge.getVertexV())) {
1444 seseLock.addConflictEdge(conflictEdge);
1445 coarseToCover.remove(conflictEdge);
1450 break;// exit iterator loop
1456 lockSet.add(seseLock);
1459 coarseToCover.addAll(notCovered);
1460 toCover.addAll(fineToCover);
1461 toCover.addAll(coarseToCover);
1465 conflictGraph2SESELock.put(conflictGraph, lockSet);
1468 public ConflictGraph getConflictGraph(FlatNode sese) {
1469 return sese2conflictGraph.get(sese);
1472 public Set<SESELock> getLockMappings(ConflictGraph graph) {
1473 return conflictGraph2SESELock.get(graph);
1476 public Set<FlatSESEEnterNode> getAllSESEs() {
1477 return rblockRel.getAllSESEs();
1480 public FlatSESEEnterNode getMainSESE() {
1481 return rblockRel.getMainSESE();
1485 public void writeReports(String timeReport) throws java.io.IOException {
1487 BufferedWriter bw = new BufferedWriter(new FileWriter("ooojReport_summary.txt"));
1488 bw.write("OoOJava Analysis Results\n\n");
1489 bw.write(timeReport + "\n\n");
1490 printSESEHierarchy(bw);
1495 Iterator<MethodDescriptor> methItr = descriptorsToAnalyze.iterator();
1496 while (methItr.hasNext()) {
1497 MethodDescriptor md = methItr.next();
1498 FlatMethod fm = state.getMethodFlat(md);
1500 bw = new BufferedWriter(new FileWriter("ooojReport_" +
1501 md.getClassMethodName() +
1502 md.getSafeMethodDescriptor() +
1504 bw.write("OoOJava Results for " + md + "\n-------------------\n");
1506 //FlatSESEEnterNode implicitSESE = (FlatSESEEnterNode) fm.getNext(0);
1507 //if (!implicitSESE.getIsCallerSESEplaceholder() && implicitSESE != rblockRel.getMainSESE()) {
1508 // System.out.println(implicitSESE + " is not implicit?!");
1511 //bw.write("Dynamic vars to manage:\n " + implicitSESE.getDynamicVarSet());
1513 bw.write("\n\nLive-In, Root View\n------------------\n" + fm.printMethod(livenessGlobalView));
1514 bw.write("\n\nVariable Results-Out\n----------------\n" + fm.printMethod(variableResults));
1515 //bw.write("\n\nNot Available Results-Out\n---------------------\n"
1516 // + fm.printMethod(notAvailableResults));
1517 //bw.write("\n\nCode Plans\n----------\n" + fm.printMethod(codePlans));
1523 private void printSESEHierarchy(BufferedWriter bw) throws java.io.IOException {
1524 bw.write("SESE Local Hierarchy\n--------------\n");
1525 Iterator<FlatSESEEnterNode> rootItr = rblockRel.getLocalRootSESEs().iterator();
1526 while (rootItr.hasNext()) {
1527 FlatSESEEnterNode root = rootItr.next();
1528 printSESEHierarchyTree(bw, root, 0);
1532 private void printSESEHierarchyTree(BufferedWriter bw,
1533 FlatSESEEnterNode fsen,
1535 ) throws java.io.IOException {
1536 for (int i = 0; i < depth; ++i) {
1539 bw.write("- " + fsen.getPrettyIdentifier() + "\n");
1541 Iterator<FlatSESEEnterNode> childItr = fsen.getLocalChildren().iterator();
1542 while (childItr.hasNext()) {
1543 FlatSESEEnterNode fsenChild = childItr.next();
1544 printSESEHierarchyTree(bw, fsenChild, depth + 1);
1548 private void printSESEInfo(BufferedWriter bw) throws java.io.IOException {
1549 bw.write("\nSESE info\n-------------\n");
1550 Iterator<FlatSESEEnterNode> fsenItr = rblockRel.getAllSESEs().iterator();
1551 while( fsenItr.hasNext() ) {
1552 FlatSESEEnterNode fsen = fsenItr.next();
1554 bw.write("SESE " + fsen.getPrettyIdentifier());
1555 if( fsen.getIsLeafSESE() ) {
1556 bw.write(" (leaf)");
1560 bw.write(" in-set: " + fsen.getInVarSet() + "\n");
1561 Iterator<TempDescriptor> tItr = fsen.getInVarSet().iterator();
1562 while (tItr.hasNext()) {
1563 TempDescriptor inVar = tItr.next();
1564 if (fsen.getReadyInVarSet().contains(inVar)) {
1565 bw.write(" (ready) " + inVar + "\n");
1567 if (fsen.getStaticInVarSet().contains(inVar)) {
1568 bw.write(" (static) " + inVar + " from " + fsen.getStaticInVarSrc(inVar) + "\n");
1570 if (fsen.getDynamicInVarSet().contains(inVar)) {
1571 bw.write(" (dynamic)" + inVar + "\n");
1575 bw.write(" Dynamic vars to manage: " + fsen.getDynamicVarSet() + "\n");
1577 bw.write(" out-set: " + fsen.getOutVarSet() + "\n");
1579 bw.write(" local parent: " + fsen.getLocalParent() + "\n");
1580 bw.write(" local children: " + fsen.getLocalChildren() + "\n");
1582 bw.write(" possible parents: " + fsen.getParents() + "\n");
1583 bw.write(" possible children: " + fsen.getChildren() + "\n");