couple fixes to make sure out-of-context nodes get all the states they need, and...
[IRC.git] / Robust / src / Analysis / Disjoint / DisjointAnalysis.java
index bd5c39281dabfa8d0d171281a5af4dfc9a71c405..2dbe1862a744fff0ba4fe446a1a1c2c9f97fff58 100644 (file)
@@ -11,6 +11,290 @@ import java.io.*;
 
 
 public class DisjointAnalysis {
+       
+         ///////////////////////////////////////////
+         //
+         //  Public interface to discover possible
+         //  aliases in the program under analysis
+         //
+         ///////////////////////////////////////////
+       
+         public HashSet<AllocSite>
+         getFlaggedAllocationSitesReachableFromTask(TaskDescriptor td) {
+           checkAnalysisComplete();
+           return getFlaggedAllocationSitesReachableFromTaskPRIVATE(td);
+         }
+         
+         public AllocSite getAllocationSiteFromFlatNew(FlatNew fn) {
+                   checkAnalysisComplete();
+                   return getAllocSiteFromFlatNewPRIVATE(fn);
+          }      
+         
+         public AllocSite getAllocationSiteFromHeapRegionNodeID(Integer id) {
+                   checkAnalysisComplete();
+                   return mapHrnIdToAllocSite.get(id);
+         }
+         
+         public Set<HeapRegionNode> createsPotentialAliases(Descriptor taskOrMethod,
+              int paramIndex1,
+              int paramIndex2) {
+                 checkAnalysisComplete();
+                 ReachGraph rg=mapDescriptorToCompleteReachGraph.get(taskOrMethod);
+                 FlatMethod fm=state.getMethodFlat(taskOrMethod);
+                 assert(rg != null);
+                 return rg.mayReachSharedObjects(fm, paramIndex1, paramIndex2);
+         }
+         
+       public Set<HeapRegionNode> createsPotentialAliases(Descriptor taskOrMethod,
+                       int paramIndex, AllocSite alloc) {
+               checkAnalysisComplete();
+               ReachGraph rg = mapDescriptorToCompleteReachGraph.get(taskOrMethod);
+           FlatMethod fm=state.getMethodFlat(taskOrMethod);
+               assert (rg != null);
+               return rg.mayReachSharedObjects(fm, paramIndex, alloc);
+       }
+
+       public Set<HeapRegionNode> createsPotentialAliases(Descriptor taskOrMethod,
+                       AllocSite alloc, int paramIndex) {
+               checkAnalysisComplete();
+               ReachGraph rg  = mapDescriptorToCompleteReachGraph.get(taskOrMethod);
+               FlatMethod fm=state.getMethodFlat(taskOrMethod);
+               assert (rg != null);
+               return rg.mayReachSharedObjects(fm, paramIndex, alloc);
+       }
+
+       public Set<HeapRegionNode> createsPotentialAliases(Descriptor taskOrMethod,
+                       AllocSite alloc1, AllocSite alloc2) {
+               checkAnalysisComplete();
+               ReachGraph rg  = mapDescriptorToCompleteReachGraph.get(taskOrMethod);
+               assert (rg != null);
+               return rg.mayReachSharedObjects(alloc1, alloc2);
+       }
+       
+       public String prettyPrintNodeSet(Set<HeapRegionNode> s) {
+               checkAnalysisComplete();
+
+               String out = "{\n";
+
+               Iterator<HeapRegionNode> i = s.iterator();
+               while (i.hasNext()) {
+                       HeapRegionNode n = i.next();
+
+                       AllocSite as = n.getAllocSite();
+                       if (as == null) {
+                               out += "  " + n.toString() + ",\n";
+                       } else {
+                               out += "  " + n.toString() + ": " + as.toStringVerbose()
+                                               + ",\n";
+                       }
+               }
+
+               out += "}\n";
+               return out;
+       }
+       
+       // use the methods given above to check every possible alias
+         // between task parameters and flagged allocation sites reachable
+         // from the task
+         public void writeAllAliases(String outputFile, 
+                                     String timeReport,
+                                     String justTime,
+                                     boolean tabularOutput,
+                                     int numLines
+)
+                       throws java.io.IOException {
+               checkAnalysisComplete();
+
+               BufferedWriter bw = new BufferedWriter(new FileWriter(outputFile));
+
+               if (!tabularOutput) {
+                       bw.write("Conducting ownership analysis with allocation depth = "
+                                       + allocationDepth + "\n");
+                       bw.write(timeReport + "\n");
+               }
+
+               int numAlias = 0;
+
+               // look through every task for potential aliases
+               Iterator taskItr = state.getTaskSymbolTable().getDescriptorsIterator();
+               while (taskItr.hasNext()) {
+                       TaskDescriptor td = (TaskDescriptor) taskItr.next();
+
+                       if (!tabularOutput) {
+                               bw.write("\n---------" + td + "--------\n");
+                       }
+
+                       HashSet<AllocSite> allocSites = getFlaggedAllocationSitesReachableFromTask(td);
+
+                       Set<HeapRegionNode> common;
+
+                       // for each task parameter, check for aliases with
+                       // other task parameters and every allocation site
+                       // reachable from this task
+                       boolean foundSomeAlias = false;
+
+                       FlatMethod fm = state.getMethodFlat(td);
+                       for (int i = 0; i < fm.numParameters(); ++i) {
+
+                               // for the ith parameter check for aliases to all
+                               // higher numbered parameters
+                               for (int j = i + 1; j < fm.numParameters(); ++j) {
+                                       common = createsPotentialAliases(td, i, j);
+                                       if (!common.isEmpty()) {
+                                               foundSomeAlias = true;
+                                               if (!tabularOutput) {
+                                                       bw.write("Potential alias between parameters " + i
+                                                                       + " and " + j + ".\n");
+                                                       bw.write(prettyPrintNodeSet(common) + "\n");
+                                               } else {
+                                                       ++numAlias;
+                                               }
+                                       }
+                               }
+
+                               // for the ith parameter, check for aliases against
+                               // the set of allocation sites reachable from this
+                               // task context
+                               Iterator allocItr = allocSites.iterator();
+                               while (allocItr.hasNext()) {
+                                       AllocSite as = (AllocSite) allocItr.next();
+                                       common = createsPotentialAliases(td, i, as);
+                                       if (!common.isEmpty()) {
+                                               foundSomeAlias = true;
+                                               if (!tabularOutput) {
+                                                       bw.write("Potential alias between parameter " + i
+                                                                       + " and " + as.getFlatNew() + ".\n");
+                                                       bw.write(prettyPrintNodeSet(common) + "\n");
+                                               } else {
+                                                       ++numAlias;
+                                               }
+                                       }
+                               }
+                       }
+
+                       // for each allocation site check for aliases with
+                       // other allocation sites in the context of execution
+                       // of this task
+                       HashSet<AllocSite> outerChecked = new HashSet<AllocSite>();
+                       Iterator allocItr1 = allocSites.iterator();
+                       while (allocItr1.hasNext()) {
+                               AllocSite as1 = (AllocSite) allocItr1.next();
+
+                               Iterator allocItr2 = allocSites.iterator();
+                               while (allocItr2.hasNext()) {
+                                       AllocSite as2 = (AllocSite) allocItr2.next();
+
+                                       if (!outerChecked.contains(as2)) {
+                                               common = createsPotentialAliases(td, as1, as2);
+
+                                               if (!common.isEmpty()) {
+                                                       foundSomeAlias = true;
+                                                       if (!tabularOutput) {
+                                                               bw.write("Potential alias between "
+                                                                               + as1.getFlatNew() + " and "
+                                                                               + as2.getFlatNew() + ".\n");
+                                                               bw.write(prettyPrintNodeSet(common) + "\n");
+                                                       } else {
+                                                               ++numAlias;
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               outerChecked.add(as1);
+                       }
+
+                       if (!foundSomeAlias) {
+                               if (!tabularOutput) {
+                                       bw.write("No aliases between flagged objects in Task " + td
+                                                       + ".\n");
+                               }
+                       }
+               }
+
+               /*
+               if (!tabularOutput) {
+                       bw.write("\n" + computeAliasContextHistogram());
+               } else {
+                       bw.write(" & " + numAlias + " & " + justTime + " & " + numLines
+                                       + " & " + numMethodsAnalyzed() + " \\\\\n");
+               }
+               */
+
+               bw.close();
+       }
+       
+       // this version of writeAllAliases is for Java programs that have no tasks
+         public void writeAllAliasesJava(String outputFile, 
+                                         String timeReport,
+                                         String justTime,
+                                         boolean tabularOutput,
+                                         int numLines
+)
+                       throws java.io.IOException {
+               checkAnalysisComplete();
+
+               assert !state.TASK;
+
+               BufferedWriter bw = new BufferedWriter(new FileWriter(outputFile));
+
+               bw.write("Conducting ownership analysis with allocation depth = "
+                               + allocationDepth + "\n");
+               bw.write(timeReport + "\n\n");
+
+               boolean foundSomeAlias = false;
+
+               Descriptor d = typeUtil.getMain();
+               HashSet<AllocSite> allocSites = getFlaggedAllocationSites(d);
+
+               // for each allocation site check for aliases with
+               // other allocation sites in the context of execution
+               // of this task
+               HashSet<AllocSite> outerChecked = new HashSet<AllocSite>();
+               Iterator allocItr1 = allocSites.iterator();
+               while (allocItr1.hasNext()) {
+                       AllocSite as1 = (AllocSite) allocItr1.next();
+
+                       Iterator allocItr2 = allocSites.iterator();
+                       while (allocItr2.hasNext()) {
+                               AllocSite as2 = (AllocSite) allocItr2.next();
+
+                               if (!outerChecked.contains(as2)) {
+                                       Set<HeapRegionNode> common = createsPotentialAliases(d,
+                                                       as1, as2);
+
+                                       if (!common.isEmpty()) {
+                                               foundSomeAlias = true;
+                                               bw.write("Potential alias between "
+                                                               + as1.getDisjointAnalysisId() + " and "
+                                                               + as2.getDisjointAnalysisId() + ".\n");
+                                               bw.write(prettyPrintNodeSet(common) + "\n");
+                                       }
+                               }
+                       }
+
+                       outerChecked.add(as1);
+               }
+
+               if (!foundSomeAlias) {
+                       bw.write("No aliases between flagged objects found.\n");
+               }
+
+//             bw.write("\n" + computeAliasContextHistogram());
+               bw.close();
+       }
+         
+         ///////////////////////////////////////////
+         //
+         // end public interface
+         //
+         ///////////////////////////////////////////
+
+         protected void checkAnalysisComplete() {
+                   if( !analysisComplete ) {
+                     throw new Error("Warning: public interface method called while analysis is running.");
+                   }
+         } 
 
 
   // data from the compiler
@@ -20,6 +304,14 @@ public class DisjointAnalysis {
   public ArrayReferencees arrayReferencees;
   public TypeUtil         typeUtil;
   public int              allocationDepth;
+  
+  // data structure for public interface
+  private Hashtable<Descriptor,    HashSet<AllocSite> > mapDescriptorToAllocSiteSet;
+
+  
+  // for public interface methods to warn that they
+  // are grabbing results during analysis
+  private boolean analysisComplete;
 
 
   // used to identify HeapRegionNode objects
@@ -115,7 +407,10 @@ public class DisjointAnalysis {
   // unique filenames
   protected Hashtable<Descriptor, Integer>
     mapDescriptorToNumUpdates;
-
+  
+  //map task descriptor to initial task parameter 
+  protected Hashtable<Descriptor, ReachGraph>
+  mapDescriptorToReachGraph;
 
 
   // allocate various structures that are not local
@@ -152,6 +447,12 @@ public class DisjointAnalysis {
 
     mapDescriptorToPriority =
       new Hashtable<Descriptor, Integer>();
+    
+    mapDescriptorToAllocSiteSet =
+       new Hashtable<Descriptor,    HashSet<AllocSite> >();
+    
+    mapDescriptorToReachGraph = 
+       new Hashtable<Descriptor, ReachGraph>();
   }
 
 
@@ -173,6 +474,8 @@ public class DisjointAnalysis {
                        Liveness         liveness,
                        ArrayReferencees arrayReferencees
                        ) throws java.io.IOException {
+         
+       analysisComplete = false;
     
     this.state                   = state;
     this.typeUtil                = typeUtil;
@@ -193,6 +496,7 @@ public class DisjointAnalysis {
 
     // start interprocedural fixed-point computation
     analyzeMethods();
+    analysisComplete=true;
 
     double timeEndAnalysis = (double) System.nanoTime();
     double dt = (timeEndAnalysis - timeStartAnalysis)/(Math.pow( 10.0, 9.0 ) );
@@ -211,6 +515,7 @@ public class DisjointAnalysis {
     if( state.DISJOINTALIASFILE != null ) {
       if( state.TASK ) {
         // not supporting tasks yet...
+         writeAllAliases(state.OWNERSHIPALIASFILE, treport, justtime, state.OWNERSHIPALIASTAB, state.lines);
       } else {
         /*
         writeAllAliasesJava( aliasFile, 
@@ -297,7 +602,7 @@ public class DisjointAnalysis {
 
       ReachGraph rg     = analyzeMethod( d );
       ReachGraph rgPrev = getPartial( d );
-
+      
       if( !rg.equals( rgPrev ) ) {
         setPartial( d, rg );
 
@@ -346,10 +651,17 @@ public class DisjointAnalysis {
       // to see if anything was updated.
 
       ReachGraph rg = new ReachGraph();
-      
-      if(fn instanceof FlatMethod && ((FlatMethod)fn).getTask()!=null){
-         // create initial reach graph for a task
-         rg=createInitialTaskReachGraph((FlatMethod)fn);
+      TaskDescriptor taskDesc;
+      if(fn instanceof FlatMethod && (taskDesc=((FlatMethod)fn).getTask())!=null){
+         if(mapDescriptorToReachGraph.containsKey(taskDesc)){
+                 // retrieve existing reach graph if it is not first time
+                 rg=mapDescriptorToReachGraph.get(taskDesc);
+         }else{
+                 // create initial reach graph for a task
+                 rg=createInitialTaskReachGraph((FlatMethod)fn);
+                 rg.globalSweep();
+                 mapDescriptorToReachGraph.put(taskDesc, rg);
+         }
       }
 
       // start by merging all node's parents' graphs
@@ -357,25 +669,29 @@ public class DisjointAnalysis {
        FlatNode pn = fn.getPrev( i );
        if( mapFlatNodeToReachGraph.containsKey( pn ) ) {
          ReachGraph rgParent = mapFlatNodeToReachGraph.get( pn );
+//       System.out.println("parent="+pn+"->"+rgParent);
          rg.merge( rgParent );
        }
       }
 
+
       if( takeDebugSnapshots && 
-         d.getSymbol().equals( descSymbolDebug ) 
+         d.getSymbol().equals( descSymbolDebug ) 
           ) {
-       debugSnapshot( rg, fn, true );
+       debugSnapshot( rg, fn, true );
       }
 
       // modify rg with appropriate transfer function
       rg = analyzeFlatNode( d, fm, fn, setReturns, rg );
-          
+
+
       if( takeDebugSnapshots && 
-         d.getSymbol().equals( descSymbolDebug ) 
+         d.getSymbol().equals( descSymbolDebug ) 
           ) {
-       debugSnapshot( rg, fn, false );
+       debugSnapshot( rg, fn, false );
       }
-
+          
 
       // if the results of the new graph are different from
       // the current graph at this node, replace the graph
@@ -406,7 +722,6 @@ public class DisjointAnalysis {
 
       completeGraph.merge( rgRet );
     }
-    
     return completeGraph;
   }
 
@@ -714,12 +1029,11 @@ public class DisjointAnalysis {
 
       try {        
        rg.writeGraph( "COMPLETE"+d,
-                       true,   // write labels (variables)
-                       true,   // selectively hide intermediate temp vars
-                       true,   // prune unreachable heap regions
-                       false,  // show back edges to confirm graph validity
-                       true,   // hide subset reachability states
-                       true ); // hide edge taints
+                       true,   // write labels (variables)                
+                       true,   // selectively hide intermediate temp vars 
+                       true,   // prune unreachable heap regions          
+                       false,  // hide subset reachability states         
+                       true ); // hide edge taints                        
       } catch( IOException e ) {}    
     }
   }
@@ -742,8 +1056,7 @@ public class DisjointAnalysis {
                          true,   // write labels (variables)
                          false,  // selectively hide intermediate temp vars
                          false,  // prune unreachable heap regions
-                         false,  // show back edges to confirm graph validity
-                         true,   // hide subset reachability states
+                         false,  // hide subset reachability states
                          true ); // hide edge taints
         } catch( IOException e ) {}    
       }
@@ -1228,12 +1541,10 @@ private ReachGraph createInitialTaskReachGraph(FlatMethod fm) {
            new Hashtable<TypeDescriptor, HeapRegionNode>();
        Set<String> doneSet = new HashSet<String>();
        
-       TempDescriptor tempDesc = new TempDescriptor(paramDesc.getSymbol(),
-                                                    paramTypeDesc);
+       TempDescriptor tempDesc = fm.getParameter(idx);
        
        AllocSite as = createParameterAllocSite(rg, tempDesc);
        VariableNode lnX = rg.getVariableNodeFromTemp(tempDesc);
-       
        Integer idNewest = as.getIthOldest(0);
        HeapRegionNode hrnNewest = rg.id2hrn.get(idNewest);
        // make a new reference to allocated node
@@ -1251,7 +1562,7 @@ private ReachGraph createInitialTaskReachGraph(FlatMethod fm) {
        for (Iterator it = classDesc.getFields(); it.hasNext();) {
            FieldDescriptor fd = (FieldDescriptor) it.next();
            TypeDescriptor fieldType = fd.getType();
-           if (!fieldType.isImmutable()) {
+           if (!fieldType.isImmutable() || fieldType.isArray()) {
                HashMap<HeapRegionNode, FieldDescriptor> newMap = new HashMap<HeapRegionNode, FieldDescriptor>();
                newMap.put(hrnNewest, fd);
                workSet.add(newMap);
@@ -1299,6 +1610,7 @@ private ReachGraph createInitialTaskReachGraph(FlatMethod fm) {
                                                   ExistPredSet.factory(), // predicates
                                                   strDesc // description
                                                   );
+                   rg.id2hrn.put(allocSite.getSummary(),hrnSummary);
                    
                    // make a new reference to summary node
                    RefEdge edgeToSummary = new RefEdge(srcHRN, // source
@@ -1316,7 +1628,8 @@ private ReachGraph createInitialTaskReachGraph(FlatMethod fm) {
                    mapTypeToExistingSummaryNode.put(type, hrnSummary);
                    
                    // set-up a work set for  fields of the class
-                   classDesc = type.getClassDesc();
+                   if(!type.isImmutable()){
+                   classDesc = type.getClassDesc();                
                    for (Iterator it = classDesc.getFields(); it.hasNext();) {
                        FieldDescriptor typeFieldDesc = (FieldDescriptor) it.next();
                        TypeDescriptor fieldType = typeFieldDesc.getType();
@@ -1331,6 +1644,7 @@ private ReachGraph createInitialTaskReachGraph(FlatMethod fm) {
                            }
                        }
                    }
+                   }
                    
                }else{
                    // if there exists corresponding summary node
@@ -1352,18 +1666,150 @@ private ReachGraph createInitialTaskReachGraph(FlatMethod fm) {
 //    debugSnapshot(rg, fm, true);
     return rg;
 }
+
+// return all allocation sites in the method (there is one allocation
+// site per FlatNew node in a method)
+private HashSet<AllocSite> getAllocationSiteSet(Descriptor d) {
+  if( !mapDescriptorToAllocSiteSet.containsKey(d) ) {
+    buildAllocationSiteSet(d);
+  }
+
+  return mapDescriptorToAllocSiteSet.get(d);
+
+}
+
+private void buildAllocationSiteSet(Descriptor d) {
+    HashSet<AllocSite> s = new HashSet<AllocSite>();
+
+    FlatMethod fm;
+    if( d instanceof MethodDescriptor ) {
+      fm = state.getMethodFlat( (MethodDescriptor) d);
+    } else {
+      assert d instanceof TaskDescriptor;
+      fm = state.getMethodFlat( (TaskDescriptor) d);
+    }
+
+    // visit every node in this FlatMethod's IR graph
+    // and make a set of the allocation sites from the
+    // FlatNew node's visited
+    HashSet<FlatNode> visited = new HashSet<FlatNode>();
+    HashSet<FlatNode> toVisit = new HashSet<FlatNode>();
+    toVisit.add(fm);
+
+    while( !toVisit.isEmpty() ) {
+      FlatNode n = toVisit.iterator().next();
+
+      if( n instanceof FlatNew ) {
+       s.add(getAllocSiteFromFlatNewPRIVATE( (FlatNew) n) );
+      }
+
+      toVisit.remove(n);
+      visited.add(n);
+
+      for( int i = 0; i < n.numNext(); ++i ) {
+       FlatNode child = n.getNext(i);
+       if( !visited.contains(child) ) {
+         toVisit.add(child);
+       }
+      }
+    }
+
+    mapDescriptorToAllocSiteSet.put(d, s);
+  }
+
+       private HashSet<AllocSite> getFlaggedAllocationSites(Descriptor dIn) {
+
+               HashSet<AllocSite> out = new HashSet<AllocSite>();
+               HashSet<Descriptor> toVisit = new HashSet<Descriptor>();
+               HashSet<Descriptor> visited = new HashSet<Descriptor>();
+
+               toVisit.add(dIn);
+
+               while (!toVisit.isEmpty()) {
+                       Descriptor d = toVisit.iterator().next();
+                       toVisit.remove(d);
+                       visited.add(d);
+
+                       HashSet<AllocSite> asSet = getAllocationSiteSet(d);
+                       Iterator asItr = asSet.iterator();
+                       while (asItr.hasNext()) {
+                               AllocSite as = (AllocSite) asItr.next();
+                               if (as.getDisjointAnalysisId() != null) {
+                                       out.add(as);
+                               }
+                       }
+
+                       // enqueue callees of this method to be searched for
+                       // allocation sites also
+                       Set callees = callGraph.getCalleeSet(d);
+                       if (callees != null) {
+                               Iterator methItr = callees.iterator();
+                               while (methItr.hasNext()) {
+                                       MethodDescriptor md = (MethodDescriptor) methItr.next();
+
+                                       if (!visited.contains(md)) {
+                                               toVisit.add(md);
+                                       }
+                               }
+                       }
+               }
+
+               return out;
+       }
     
+private HashSet<AllocSite>
+getFlaggedAllocationSitesReachableFromTaskPRIVATE(TaskDescriptor td) {
+
+  HashSet<AllocSite> asSetTotal = new HashSet<AllocSite>();
+  HashSet<Descriptor>     toVisit    = new HashSet<Descriptor>();
+  HashSet<Descriptor>     visited    = new HashSet<Descriptor>();
+
+  toVisit.add(td);
+
+  // traverse this task and all methods reachable from this task
+  while( !toVisit.isEmpty() ) {
+    Descriptor d = toVisit.iterator().next();
+    toVisit.remove(d);
+    visited.add(d);
+
+    HashSet<AllocSite> asSet = getAllocationSiteSet(d);
+    Iterator asItr = asSet.iterator();
+    while( asItr.hasNext() ) {
+       AllocSite as = (AllocSite) asItr.next();
+       TypeDescriptor typed = as.getType();
+       if( typed != null ) {
+         ClassDescriptor cd = typed.getClassDesc();
+         if( cd != null && cd.hasFlags() ) {
+           asSetTotal.add(as);
+         }
+       }
+    }
 
+    // enqueue callees of this method to be searched for
+    // allocation sites also
+    Set callees = callGraph.getCalleeSet(d);
+    if( callees != null ) {
+       Iterator methItr = callees.iterator();
+       while( methItr.hasNext() ) {
+         MethodDescriptor md = (MethodDescriptor) methItr.next();
 
+         if( !visited.contains(md) ) {
+           toVisit.add(md);
+         }
+       }
+    }
+  }
 
-  int zzz = 0;
+  return asSetTotal;
+}
 
 
   
   
   // get successive captures of the analysis state
   boolean takeDebugSnapshots = false;
-  String descSymbolDebug = "addBar";
+  String descSymbolDebug = "addSomething";
   boolean stopAfterCapture = true;
 
   // increments every visit to debugSnapshot, don't fiddle with it
@@ -1377,11 +1823,12 @@ private ReachGraph createInitialTaskReachGraph(FlatMethod fm) {
   int freqCountReport = 0;
 
   // the debugCounter value at which to start taking snapshots
-  int iterStartCapture = 0;
+  int iterStartCapture = 25;
 
   // the number of snapshots to take
   int numIterToCapture = 300;
 
+
   void debugSnapshot( ReachGraph rg, FlatNode fn, boolean in ) {
     if( debugCounter > iterStartCapture + numIterToCapture ) {
       return;
@@ -1417,10 +1864,9 @@ private ReachGraph createInitialTaskReachGraph(FlatMethod fm) {
       try {
        rg.writeGraph( graphName,
                        true,  // write labels (variables)
-                       false, // selectively hide intermediate temp vars
-                       false, // prune unreachable heap regions
-                       false, // show back edges to confirm graph validity
-                       true,  // hide subset reachability states
+                       true,  // selectively hide intermediate temp vars
+                       true,  // prune unreachable heap regions
+                       false, // hide subset reachability states
                        true );// hide edge taints
       } catch( Exception e ) {
        System.out.println( "Error writing debug capture." );