Fix implementation to use little d when possible, and big D only if there's no other...
[IRC.git] / Robust / src / Analysis / OwnershipAnalysis / OwnershipAnalysis.java
index 1c3707df48a72e414651452edf029d9d593135b4..f28ce12748ca6ff676da5b1323ef6736637c45d7 100644 (file)
@@ -70,13 +70,14 @@ public class OwnershipAnalysis {
 
     BufferedWriter bw = new BufferedWriter(new FileWriter(outputFile) );
 
+    bw.write("Conducting ownership analysis with allocation depth = "+allocationDepth);
+
     // look through every task for potential aliases
     Iterator taskItr = state.getTaskSymbolTable().getDescriptorsIterator();
     while( taskItr.hasNext() ) {
       TaskDescriptor td = (TaskDescriptor) taskItr.next();
 
       bw.write("\n---------"+td+"--------\n");
-      bw.flush();
 
       HashSet<AllocationSite> allocSites = getFlaggedAllocationSitesReachableFromTask(td);
 
@@ -105,7 +106,7 @@ public class OwnershipAnalysis {
          AllocationSite as = (AllocationSite) allocItr.next();
          if( createsPotentialAliases(td, i, as) ) {
            foundSomeAlias = true;
-           bw.write("Potential alias between parameter "+i+" and "+as+".\n");
+           bw.write("Potential alias between parameter "+i+" and "+as.getFlatNew()+".\n");
          }
        }
       }
@@ -125,7 +126,7 @@ public class OwnershipAnalysis {
          if( !outerChecked.contains(as2) &&
              createsPotentialAliases(td, as1, as2) ) {
            foundSomeAlias = true;
-           bw.write("Potential alias between "+as1+" and "+as2+".\n");
+           bw.write("Potential alias between "+as1.getFlatNew()+" and "+as2.getFlatNew()+".\n");
          }
        }
 
@@ -203,8 +204,8 @@ public class OwnershipAnalysis {
                                                                  null,
                                                                  false);
   // for controlling DOT file output
-  private boolean writeFinalGraphs;
-  private boolean writeAllUpdates;
+  private boolean writeDOTs;
+  private boolean writeAllDOTs;
 
 
 
@@ -214,15 +215,16 @@ public class OwnershipAnalysis {
                            TypeUtil tu,
                            CallGraph callGraph,
                            int allocationDepth,
-                           boolean writeFinalGraphs,
-                           boolean writeAllUpdates) throws java.io.IOException {
+                           boolean writeDOTs,
+                           boolean writeAllDOTs,
+                           String aliasFile) throws java.io.IOException {
 
-    this.state            = state;
-    this.typeUtil         = tu;
-    this.callGraph        = callGraph;
-    this.allocationDepth  = allocationDepth;
-    this.writeFinalGraphs = writeFinalGraphs;
-    this.writeAllUpdates  = writeAllUpdates;
+    this.state           = state;
+    this.typeUtil        = tu;
+    this.callGraph       = callGraph;
+    this.allocationDepth = allocationDepth;
+    this.writeDOTs       = writeDOTs;
+    this.writeAllDOTs    = writeAllDOTs;
 
     descriptorsToAnalyze = new HashSet<Descriptor>();
 
@@ -238,7 +240,7 @@ public class OwnershipAnalysis {
     mapDescriptorToAllocationSiteSet =
       new Hashtable<Descriptor, HashSet<AllocationSite> >();
 
-    if( writeAllUpdates ) {
+    if( writeAllDOTs ) {
       mapDescriptorToNumUpdates = new Hashtable<Descriptor, Integer>();
     }
 
@@ -279,7 +281,11 @@ public class OwnershipAnalysis {
     // a method if the methods that it calls are updated
     analyzeMethods();
 
-    writeAllAliases("identifiedAliases.txt");
+    System.out.println("");
+
+    if( aliasFile != null ) {
+      writeAllAliases(aliasFile);
+    }
   }
 
   // called from the constructor to help initialize the set
@@ -341,7 +347,6 @@ public class OwnershipAnalysis {
       OwnershipGraph og = analyzeFlatMethod(d, fm);
       OwnershipGraph ogPrev = mapDescriptorToCompleteOwnershipGraph.get(d);
       if( !og.equals(ogPrev) ) {
-
        setGraphForDescriptor(d, og);
 
        // only methods have dependents, tasks cannot
@@ -391,6 +396,8 @@ public class OwnershipAnalysis {
       FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
       flatNodesToVisit.remove(fn);
 
+      //System.out.println( "  "+fn );
+
       // perform this node's contributions to the ownership
       // graph on a new copy, then compare it to the old graph
       // at this node to see if anything was updated.
@@ -398,9 +405,11 @@ public class OwnershipAnalysis {
 
       // start by merging all node's parents' graphs
       for( int i = 0; i < fn.numPrev(); ++i ) {
-       FlatNode pn       = fn.getPrev(i);
-       OwnershipGraph ogParent = getGraphFromFlatNode(pn);
-       og.merge(ogParent);
+       FlatNode pn = fn.getPrev(i);    
+       if( mapFlatNodeToOwnershipGraph.containsKey(pn) ) {
+         OwnershipGraph ogParent = mapFlatNodeToOwnershipGraph.get(pn);
+         og.merge(ogParent);
+       }
       }
 
       // apply the analysis of the flat node to the
@@ -411,14 +420,19 @@ public class OwnershipAnalysis {
                            returnNodesToCombineForCompleteOwnershipGraph,
                            og);
 
+
+
+      //debugSnapshot(og,fn);
+
+
+
       // if the results of the new graph are different from
       // the current graph at this node, replace the graph
       // with the update and enqueue the children for
       // processing
-      OwnershipGraph ogPrev = getGraphFromFlatNode(fn);
-
+      OwnershipGraph ogPrev = mapFlatNodeToOwnershipGraph.get(fn);
       if( !og.equals(ogPrev) ) {
-       setGraphForFlatNode(fn, og);
+       mapFlatNodeToOwnershipGraph.put(fn, og);
 
        for( int i = 0; i < fn.numNext(); i++ ) {
          FlatNode nn = fn.getNext(i);
@@ -434,9 +448,11 @@ public class OwnershipAnalysis {
     Iterator retItr = returnNodesToCombineForCompleteOwnershipGraph.iterator();
     while( retItr.hasNext() ) {
       FlatReturnNode frn = (FlatReturnNode) retItr.next();
-      OwnershipGraph ogr = getGraphFromFlatNode(frn);
+      assert mapFlatNodeToOwnershipGraph.containsKey(frn);
+      OwnershipGraph ogr = mapFlatNodeToOwnershipGraph.get(frn);
       completeGraph.merge(ogr);
-    }
+    }   
+
     return completeGraph;
   }
 
@@ -502,7 +518,7 @@ public class OwnershipAnalysis {
       lhs = ffn.getDst();
       rhs = ffn.getSrc();
       fld = ffn.getField();
-      if( !fld.getType().isPrimitive() ) {
+      if( !fld.getType().isImmutable() ) {
        og.assignTempXEqualToTempYFieldF(lhs, rhs, fld);
       }
       break;
@@ -512,14 +528,16 @@ public class OwnershipAnalysis {
       lhs = fsfn.getDst();
       fld = fsfn.getField();
       rhs = fsfn.getSrc();
-      og.assignTempXFieldFEqualToTempY(lhs, fld, rhs);
+      if( !fld.getType().isImmutable() ) {
+       og.assignTempXFieldFEqualToTempY(lhs, fld, rhs);
+      }
       break;
 
     case FKind.FlatElementNode:
       FlatElementNode fen = (FlatElementNode) fn;
       lhs = fen.getDst();
       rhs = fen.getSrc();
-      if( !lhs.getType().isPrimitive() ) {
+      if( !lhs.getType().isImmutable() ) {
        og.assignTempXEqualToTempYFieldF(lhs, rhs, fdElement);
       }
       break;
@@ -528,7 +546,7 @@ public class OwnershipAnalysis {
       FlatSetElementNode fsen = (FlatSetElementNode) fn;
       lhs = fsen.getDst();
       rhs = fsen.getSrc();
-      if( !rhs.getType().isPrimitive() ) {
+      if( !rhs.getType().isImmutable() ) {
        og.assignTempXFieldFEqualToTempY(lhs, fdElement, rhs);
       }
       break;
@@ -536,9 +554,10 @@ public class OwnershipAnalysis {
     case FKind.FlatNew:
       FlatNew fnn = (FlatNew) fn;
       lhs = fnn.getDst();
-      AllocationSite as = getAllocationSiteFromFlatNewPRIVATE(fnn);
-
-      og.assignTempEqualToNewAlloc(lhs, as);
+      if( !lhs.getType().isImmutable() ) {
+       AllocationSite as = getAllocationSiteFromFlatNewPRIVATE(fnn);
+       og.assignTempEqualToNewAlloc(lhs, as);
+      }
       break;
 
     case FKind.FlatCall:
@@ -574,17 +593,15 @@ public class OwnershipAnalysis {
        }
       }
 
-      og = ogMergeOfAllPossibleCalleeResults;
+      og = ogMergeOfAllPossibleCalleeResults;      
       break;
 
     case FKind.FlatReturnNode:
       FlatReturnNode frn = (FlatReturnNode) fn;
       rhs = frn.getReturnTemp();
-
-      if( rhs != null ) {
+      if( rhs != null && !rhs.getType().isImmutable() ) {
        og.assignReturnEqualToTemp(rhs);
       }
-
       setRetNodes.add(frn);
       break;
     }
@@ -593,6 +610,40 @@ public class OwnershipAnalysis {
   }
 
 
+  // insert a call to debugSnapshot() somewhere in the analysis to get
+  // successive captures of the analysis state
+  int debugCounter        = 0;
+  int numStartCountReport = 10000;
+  int freqCountReport     = 10;
+  int iterStartCapture    = 50;
+  int numIterToCapture    = 16;
+  void debugSnapshot( OwnershipGraph og, FlatNode fn ) {
+    ++debugCounter;
+    if( debugCounter > numStartCountReport &&
+       debugCounter % freqCountReport == 0 ) {
+      System.out.println( "    @@@ debug counter = "+debugCounter );
+    }
+    if( debugCounter > iterStartCapture ) {
+      System.out.println( "    @@@ capturing debug "+(debugCounter-iterStartCapture)+" @@@" );
+      String graphName = String.format("snap%04d",debugCounter-iterStartCapture);
+      if( fn != null ) {
+       graphName = graphName+fn;
+      }
+      try {
+       og.writeGraph( graphName, true, true, true, false, false );
+      } catch( Exception e ) {
+       System.out.println( "Error writing debug capture." );
+       System.exit( 0 );       
+      }
+    }
+    if( debugCounter == iterStartCapture + numIterToCapture ) {
+      System.out.println( "Stopping analysis after debug captures." );
+      System.exit( 0 );
+    }
+  }
+
+
+
   // this method should generate integers strictly greater than zero!
   // special "shadow" regions are made from a heap region by negating
   // the ID
@@ -612,42 +663,30 @@ public class OwnershipAnalysis {
     // boolean labelSelect,
     // boolean pruneGarbage,
     // boolean writeReferencers
+    // boolean writeParamMappings
 
-    if( writeFinalGraphs ) {
+    if( writeDOTs ) {
 
-      if( !writeAllUpdates ) {
-       og.writeGraph(d, true, true, true, false);
+      if( !writeAllDOTs ) {
+       og.writeGraph(d, true, true, true, false, false);
 
       } else {
        if( !mapDescriptorToNumUpdates.containsKey(d) ) {
          mapDescriptorToNumUpdates.put(d, new Integer(0) );
        }
        Integer n = mapDescriptorToNumUpdates.get(d);
-       og.writeGraph(d, n, true, true, true, false);
+       og.writeGraph(d, n, true, true, true, false, false);
        mapDescriptorToNumUpdates.put(d, n + 1);
       }
     }
   }
 
 
-  private OwnershipGraph getGraphFromFlatNode(FlatNode fn) {
-    if( !mapFlatNodeToOwnershipGraph.containsKey(fn) ) {
-      mapFlatNodeToOwnershipGraph.put(fn, new OwnershipGraph(allocationDepth, typeUtil) );
-    }
-
-    return mapFlatNodeToOwnershipGraph.get(fn);
-  }
-
-  private void setGraphForFlatNode(FlatNode fn, OwnershipGraph og) {
-    mapFlatNodeToOwnershipGraph.put(fn, og);
-  }
-
-
   // return just the allocation site associated with one FlatNew node
   private AllocationSite getAllocationSiteFromFlatNewPRIVATE(FlatNew fn) {
 
     if( !mapFlatNewToAllocationSite.containsKey(fn) ) {
-      AllocationSite as = new AllocationSite(allocationDepth, fn.getType() );
+      AllocationSite as = new AllocationSite(allocationDepth, fn );
 
       // the newest nodes are single objects
       for( int i = 0; i < allocationDepth; ++i ) {